JSP

前言

  • JSP(Java Server Pages)是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求,而动态生成 HTML、XML 或其他格式文档的 Web 网页的技术标准。

  • JSP 技术是以 Java 语言作为脚本语言的,JSP 网页为整个服务器端的 Java 库单元提供了一个接口来服务于 HTTP 的应用程序。

  • JSP 开发的 WEB 应用可以跨平台使用,既可以运行在 Linux 上也能运行在 Windows 上。

  • JSP 教程(w3cschool)

  • JSP 教程(runoob)

  • JSP 快速入门

1、JSP

  • JSP 与 PHP、ASP、ASP.NET 等语言类似,是运行在服务端的语言。

  • JSP 文件后缀名为 *.jsp 。

    1
    2
    3
    4
    5
    6
    7
    <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*" %>

    你好 JSP

    <br />

    <%= new Date().toLocaleString() %>
  • 解析

    • <%@ page:page 指令,包含 编码类型、导入其他类 等。
    • <%= :进行输出。
  • 本地测试

2、执行过程

  • 为什么 JSP 可以在 html 中运行 Java 代码?这是因为 JSP 被转译成了 Servlet

  • JSP 执行过程

    • hello.jsp 转译为 hello_jsp.java。
    • hello_jsp.java 位于 d:\tomcat\work\Catalina\localhost\_\org\apache\jsp
    • hello_jsp.java 是一个 servlet。
    • 把 hello_jsp.java 编译为 hello_jsp.class。
    • 执行 hello_jsp,生成 html。
    • 通过 http 协议把 html 响应返回给浏览器。

3、页面元素

元素 介绍
静态内容 HTML 静态文本,就是 html,css,javascript 等内容
指令 <%@ 开始 %> 结尾,比如 <%@ page import="java.util.*"%>
表达式 <%= 开始 %> 结尾,用于输出一段 html,不需要分号结尾,比如 <%= Java 表达式 %>,相当于 <% out.println("hello jsp"); %>
Scriptlet <% %> 之间,可以写任何 Java 代码,需要以分号结尾,和 Java 代码一样
声明 <%! %> 之间,可以声明字段或者方法。但是不建议这么做
动作 <jsp:动作 />,如 <jsp:include page="Filename" /> 在 Jsp 页面中包含另一个页面
注释 <%-- --%> 通过 jsp 的注释,浏览器也看不到相应的代码,相当于在 Servlet 中注释掉了
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*" %>
    <% List<String> words = new ArrayList<String>();
    words.add("today");
    words.add("is");
    words.add("a");
    words.add("great");
    words.add("day");
    %>

    <table width="200px" align="center" border="1" cellspacing="0">

    <% for (String word : words) { %>

    <tr>
    <td>
    <%= word %>
    </td>
    </tr>

    <% } %>

    </table>
  • 本地测试

4、include

  • 每个网页的最下方都有 版权声明等信息。如果不使用包含,那么每个网页都需要单独写,如果版权声明要修改,则需要很大的工作量。

  • 使用 include 的办法,只需要准备一个 footer.jsp,然后在其他页面包含 footer.jsp 即可。

  • 修改的时候,只需要修改 footer.jsp 所有的页面就都修改了,维护成本降低了很多。

  • include 有两种方式

    • 指令 include:内容会被插入到引用的 jsp 文件中,最后只会生成一个 Java 文件。
    • 动作 include:内容不会被插入到引用的 jsp 文件中,最后还会有一个 Java 独立存在。
  • 指令 include

    1
    <%@ include file="footer.jsp" %>
  • 动作 include

    1
    <jsp:include page="footer.jsp" />
  • 本地测试

  • 传参

    • 指令 <%@ include 会导致两个 jsp 合并成为同一个 java 文件,所以就不存在传参的问题,在发出 hello.jsp 里定义的变量,直接可以在 footer.jsp 中访问。
    • 动作 <jsp:include /> 其实是对 footer.jsp 进行了一次独立的访问,那么就有传参的需要。

      1
      2
      3
      <jsp:include page="footer.jsp">
      <jsp:param name="year" value="2019" /> <%-- 发送参数 --%>
      </jsp:include>
      1
      <%= request.getParameter("year") %>             <%-- 取出参数 --%>

5、页面跳转

  • JSP 页面跳转 和 Servlet 的页面跳转一样。

  • JSP 的页面跳转也分

    • 服务端跳转:浏览器地址不会发生变化。
    • 客户端跳转:浏览器地址会发生变化。
  • 服务端跳转

    1
    2
    3
    4
    5
    <jsp:forward page="hello.jsp" />



    <% request.getRequestDispatcher("hello.jsp").forward(request, response); %>
  • 客户端跳转

    1
    <% response.sendRedirect("hello.jsp"); %>
  • 本地测试

6、Cookie

  • Cookie 是一种浏览器和服务器交互数据的方式。

  • Cookie 是由服务器端创建,但是不会保存在服务器。创建好之后,发送给浏览器,浏览器保存在用户本地。下一次访问网站的时候,就会把该 Cookie 发送给服务器。

  • 有的网站,登陆的时候,会出现一个选项,问你是否要一周内或者一个月内保持登陆状态。如果你选了,那么一周之内,都不需要再输入账号密码。这个功能,就是靠 Cookie 来实现的。

  • setCookie

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

    <%
    Cookie c = new Cookie("name", "Gareen");
    c.setMaxAge(60 * 24 * 60);
    c.setPath("/");
    response.addCookie(c);
    %>

    <a href="getCookie.jsp">跳转到获取 cookie 的页面</a>
  • getCookie

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

    <%
    Cookie[] cookies = request.getCookies();
    if (null != cookies) {
    for (int d = 0; d <= cookies.length - 1; d++) {
    out.print(cookies[d].getName() + ":" + cookies[d].getValue() + "<br>");
    }
    }
    %>
  • 本地测试

7、Session

  • Session 对应的中文翻译是会话。

  • 会话指的是从用户打开浏览器访问一个网站开始,无论在这个网站中访问了多少页面,点击了多少链接,都属于同一个会话。直到该用户关闭浏览器为止,都属于同一个会话。

  • setSession

    1
    2
    3
    4
    5
    6
    7
    8
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

    <%
    session.setAttribute("name", "teemo");
    %>

    <a href="getSession.jsp">跳转到获取 session 的页面</a>
  • getSession

    1
    2
    3
    4
    5
    6
    7
    8
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

    <%
    String name = (String)session.getAttribute("name");
    %>

    session 中的 name: <%= name %>
  • 本地测试

  • Session 和 Cookie 的关系

    • 如果浏览器把 cookie 功能关闭,那么服务端就无法获取 jsessionid,每一次访问,都会生成一个新的 session 对象。
    • 为了解决这个问题,可以使用 response.encodeURL 方法会把 getSession.jsp 这个 url 转换为 getSession.jsp;jsessionid=22424AEA86ADBE89F335EEB649D997A8
    • 通过这个方式,提交 jsessionid 到服务器。服务器根据这个 jsessionid 匹配到对应的 session。与 session 相关的功能,就可以正常工作了。

      1
      2
      3
      4
      5
      6
      7
      8
      <%@ page language="java" contentType="text/html; charset=UTF-8"
      pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>

      <%
      session.setAttribute("name", "teemo");
      %>

      <a href="<%= response.encodeURL("getSession.jsp") %>">跳转到获取 session 的页面</a>
  • 有效期

    • 在 Tomcat 默认配置下,Session 的有效期是 30 分钟。可以通过 /tomcat/conf/web.xml 中的 session-config 配置进行调整。

8、作用域

  • JSP 有 4 个作用域

    • pageContext:当前页面
    • requestContext:一次请求
    • sessionContext:当前会话
    • applicationContext:全局,所有用户共享
  • pageContext

  • requestContext

    • 随着本次请求结束,其中的数据也就被回收。

      1
      2
      3
      4
      5
      6
      7
      <% request.setAttribute("name", "gareen"); %>

      <%= request.getAttribute("name") %>


      pageContext.setAttribute("name", "gareen", pageContext.REQUEST_SCOPE);
      pageContext.getAttribute("name", pageContext.REQUEST_SCOPE)
    • 本地测试:

    • 如果发生了服务端跳转,从 setRequestContext.jsp 跳转到 getRequestContext.jsp,这其实,还是一次请求。

    • 客户端跳转,浏览器会发生一次新的访问,新的访问会产生一个新的 request 对象。所以页面间客户端跳转的情况下,是无法通过 request 传递数据的。
  • sessionContext

    • 从一个用户打开网站的那一刻起,无论访问了多少网页,链接都属于同一个会话,直到浏览器关闭。

      1
      2
      3
      4
      5
      6
      7
      <% session.setAttribute("name", "gareen"); %>

      <%= session.getAttribute("name") %>


      pageContext.setAttribute("name", "gareen", pageContext.SESSION_SCOPE);
      pageContext.getAttribute("name", pageContext.SESSION_SCOPE)
    • 本地测试:

    • 页面间传递数据,也是可以通过 session 传递的。但是,不同用户对应的 session 是不一样的,所以 session 无法在不同的用户之间共享数据。

  • applicationContext

    • application 映射的就是 web 应用本身。application 对象是 ServletContext 接口的实例。也可以通过 request.getServletContext() 来获取。

      1
      2
      3
      4
      5
      6
      7
      <% application.setAttribute("name", "gareen"); %>

      <%= application.getAttribute("name") %>


      pageContext.setAttribute("name", "gareen", pageContext.APPLICATION_SCOPE);
      pageContext.getAttribute("name", pageContext.APPLICATION_SCOPE)
    • 本地测试:

    • applicationContext 指的是全局,所有用户共享同一个数据。

9、隐式对象

  • 隐式对象指的是不需要显示定义,直接就可以使用的对象,比如 request, response
对象 介绍
request 代表请求
response 代表响应
out 代表输出
pageContext 代表当前页面作用域
session 代表当会话作用域
application 代表当全局作用域
page 表示当前对象,page 即代表 this
config 获取配置信息
exception 异常处理

10、JSTL 标准标签库

  • JSTL JSP Standard Tag Library 标准标签库。

  • 允许开人员可以像使用 HTML 标签 那样在 JSP 中开发 Java 功能。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

    <%-- prefix="c" 表示后续的标签使用都会以 <c: 开头 --%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

    <%-- 在作用域 request 中设置 name,相当于 <% request.setAttribute("name", "gareen") %> --%>
    <c:set var="name" value="${'gareen'}" scope="request" />

    <%-- 获取 name,相当于 <%= request.getAttribute("name") %> --%>
    <c:out value="${name}" />

11、EL 表达式语言

  • 为了保证 EL 表达式语言能够正常使用,需要在 <%@ page 标签里加上 isELIgnored="false"

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

    <c:set var="name" value="${'gareen'}" scope="request" />

    通过标签获取 name: <c:out value="${name}" /> <br>

    通过 EL 获取 name: ${name}
  • JavaBean 概念

    • 提供无参 public 的构造方法 (默认提供)。
    • 每个属性,都有 public 的 getter 和 setter 方法。
    • 如果属性是 boolean,那么就对应 is 和 setter 方法。
文章目录
  1. 1. 前言
  2. 2. 1、JSP
  3. 3. 2、执行过程
  4. 4. 3、页面元素
  5. 5. 4、include
  6. 6. 5、页面跳转
  7. 7. 6、Cookie
  8. 8. 7、Session
  9. 9. 8、作用域
  10. 10. 9、隐式对象
  11. 11. 10、JSTL 标准标签库
  12. 12. 11、EL 表达式语言
隐藏目录