zoukankan      html  css  js  c++  java
  • JSP 脚本中的 9 个内置对象

    JSP 脚本中包含了 9 个内置对象,这 9 个内置对象都是 Servlet API 接口的实例,只是 JSP 规范对它们进行了默认初始化。

    这 9 个内置对象如下:

    1、application:javax.servlet.ServletContext 的实例,该实例代表 JSP 所属的 Web 应用本身,可用于 JSP 页面,或者在 Servlet 之间交换信息。常用的方法有 getAttribute(String attrName)、setAttribute(String attrName, String attrValue) 和 getInitParameter(String paramName) 等。

    2、config:javax.servlet.ServletConfig 的实例,该实例代表该 JSP 的配置信息。常用的方法有 getInitParameter(String paramName) 和 getInitParameternames() 方法。

    3、exception:java.lang.Throwable 的实例,该实例代表其他页面中的异常和错误。只有当页面是错误页面,即编译指令 page 的 isErrorPage

     属性为 true 时,该对象才可以使用。常用的方法有 getMessage() 和 printStackTrace()。

    4、out:javax.servlet.jsp.JspWriter 的实例,该实例代表 JSP 页面的输出流,用于输出内容,形成 HTML 页面。

    5、page:代表该页面本身,通常没有太大用处。也就是 Servlet 中的 this,其类型就是生成的 Servlet 类,能用 page 的地方就可用 this。

    6、pageContext:javax.servlet.jsp.PageContext 的实例,该对象代表该 JSP 页面上下文,使用该对象可以访问页面中的共享数据。常用的方法有 getServletContext() 和 getServletConfig() 。

    7、request:javax.servlet.jsp.HttpServletRequest 的实例,该对象封装了一次请求,客户端的请求参数都被封装在该对象里。这是一个常用的对象,获取客户端请求参数必须使用该对象。常用的方法有 getParameter(String paramName)、getParameterValues(String paramName)、setAttribute(String attrName, Object attrValue)、getAttribute(String attrName) 和 setCharacterEncoding(String encoding)

    8、response:javax.servlet.jsp.HttpServletResponse 的实例,代表服务器对客户端的响应。通常很少直接使用该对象,而是使用 out 对象,常用的方法有 getOutputStream()、setRedirect(String location)

    9、session:javax.servlet.http.HttpSession 的实例,该对象代表一次会话。常用的方法有 getAttribute(String attrName)、setAttribute(String attrName, Object attrValue)

    打开 jsp 生成的 servlet 文件,我们可以看到内置对象的声明及初始化:

    final javax.servlet.jsp.PageContext pageContext;
        javax.servlet.http.HttpSession session = null;
        final javax.servlet.ServletContext application;
        final javax.servlet.ServletConfig config;
        javax.servlet.jsp.JspWriter out = null;
        final java.lang.Object page = this;
        javax.servlet.jsp.JspWriter _jspx_out = null;
        javax.servlet.jsp.PageContext _jspx_page_context = null;
    

      

    try {
          response.setContentType("text/html; charset=UTF-8");
          pageContext = _jspxFactory.getPageContext(this, request, response,
          			null, true, 8192, true);
          _jspx_page_context = pageContext;
          application = pageContext.getServletContext();
          config = pageContext.getServletConfig();
          session = pageContext.getSession();
          out = pageContext.getOut();
          _jspx_out = out;
    }
    

      

    上面的声明及定义位于 jspService 方法内

    application 对象

    通常有如下两个作用:

    1、让多个 JSP 、Servlet 共享数据

    application 通过 setAttribute(String attrName, Object value) 方法讲一个值设置成 application 的 attrName 属性,该属性的值对整个 Web 应用有效,因此该 web 应用的每个 JSP 页面或 Servlet 都可以访问该属性,访问属性的方法为 getAttribute(String attrName)。

    application 不仅可以用于两个 JSP 页面之间共享数据,还可以用于 Servlet 和 JSP 之间共享数据。可以把 application 理解成一个 Map 对象,任何 JSP、Servlet 都可以把某个变量放入 application 中保存,并为之指定一个变量名;而该应用里的其他 Servlet、JSP 就可以根据该属性名来得到这个变量。

    2、获得 web 应用配置参数

    application 还有一个重要用处,可用于获得 web 应用的配置参数。如下:参数都在 web.xml 中配置了。

    如下,在 web.xml 里面设置参数配置(context-param 标签):

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
      version="4.0"
      metadata-complete="true">
    
    <servlet>
        <servlet-name>get-application</servlet-name>
        <servlet-class>com.baiguiren.GetApplication</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>get-application</servlet-name>
        <url-pattern>/get-application</url-pattern>
    </servlet-mapping>
    
    <!-- 配置第一个参数:driver -->
    <context-param>
      <param-name>driver</param-name>
      <param-value>com.mysql.jdbc.Driver</param-value>
    </context-param>
    
    <!-- 配置第二个参数:url -->
    <context-param>
      <param-name>url</param-name>
      <param-value>jdbc:mysql://localhost:3306/jsp</param-value>
    </context-param>
    
    <!-- 配置第三个参数:user -->
    <context-param>
      <param-name>user</param-name>
      <param-value>root</param-value>
    </context-param>
    
    <!-- 配置第四个参数:pass -->
    <context-param>
      <param-name>pass</param-name>
      <param-value>root</param-value>
    </context-param>
    
    <welcome-file-list>
      <welcome-file>index.html</welcome-file>
      <welcome-file>index.htm</welcome-file>
      <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    </web-app>
    

      

    在 JSP 中获取参数:

    <%@ page contentType="text/html; charset=UTF-8" %>
    <%@ page import="java.sql.*" %>
    
    <html>
        <head>
            <title>通过application获取web.xml中的参数</title>
        </head>
        <body>
    <%
    // 从配置中获取参数
    String driver = application.getInitParameter("driver");
    // 从配置参数中获取数据库 url
    String url = application.getInitParameter("url");
    // 从配置参数中获取用户名
    String user = application.getInitParameter("user");
    // 从配置参数中获取密码
    String pass = application.getInitParameter("pass");
    
    // 注册驱动
    Class.forName(driver);
    // 获取数据库连接
    Connection connection = DriverManager.getConnection(url, user, pass);
    // 创建 Statement 对象
    Statement stmt = connection.createStatement();
    // 执行查询
    ResultSet rs = stmt.executeQuery("select * from person");
    %>
    
    // 输出
    <table bgcolor="#9999dd" border="1" width="480">
    <%
    // 遍历结果集
    while(rs.next())
    {
    %>
    <tr>
        <td><%=rs.getString(1)%></td>
        <td><%=rs.getString(2)%></td>
        <td><%=rs.getString(3)%></td>
    </tr>
    <%
    }
    %>
    </table>
        </body>
    </html>
    

      

     config 对象:

    config对象代表当前 JSP 配置信息,但 JSP 通常无需配置,因此也就不存在配置信息。所以 JSP 页面比较少用该对象。

    但在 Servlet 中则用处较大,因为 Servlet 需要在 web.xml 文件中进行配置,可以指定配置参数。

    如:

    web.xml 里面配置:

    <servlet>
      <!-- 指定Servlet名字 -->
      <servlet-name>config</servlet-name>
      <!-- 指定将哪个 JSP 页面配置成Servlet -->
      <jsp-file>/config.jsp</jsp-file>
      <!-- 配置名为 name 的参数,值为 ruby -->
      <init-param>
        <param-name>name</param-name>
        <param-value>ruby</param-value>
      </init-param>
      <!-- 配置名为 age 的参数,值为 24 -->
      <init-param>
        <param-name>age</param-name>
        <param-value>24</param-value>
      </init-param>
    </servlet>
    <servlet-mapping>
      <!-- 指定将 config Servlet 配置到 /config 路径 -->
      <servlet-name>config</servlet-name>
      <url-pattern>/config</url-pattern>
    </servlet-mapping>
    

      

    jsp 文件:

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <html>
        <head>
            <title>config内置对象</title>
        </head>
        <body>
            <!-- 输出该 JSP 名为 name 的配置参数 -->
            name 配置参数的值为:<%=config.getInitParameter("name")%>
            <!-- 输出该 JSP 名为 age 的配置参数 -->
            age 配置参数的值为:<%=config.getInitParameter("age")%>
        </body>
    </html>
    

      

    exception 对象

    exception 对象是 Throwable 的实例,代表 JSP 脚本中产生的错误和异常,是 JSP 页面异常机制的一部分。

    JSP 中的异常都可交给错误处理页面处理。

    如:

    首先需要在其他出现异常的页面的 page 指令中指定 errorPage 是下面的页面:

    <%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="error.jsp" %>

    又或者在 web.xml 中配置如下内容:

    error-page>
       <exception-type>java.lang.Throwable</exception-type>
       <location>/error.jsp</location>
     </error-page>
    

    error.jsp

    <%@ page contentType="text/html; charset=UTF-8" isErrorPage="true" %>
    
    <html>
        <head>
            <title>error</title>
            <link href="assets/prism/prism.css" rel="stylesheet" />
        </head>
    
        <body>
            异常类型:<pre><code class="language-java"></code><%=exception.getClass()%></code></pre><br/>
            异常信息:<pre><code class="language-java"><%=exception.getMessage()%></code></pre><br/>
            错误堆栈:<pre><code class="language-java"></code><%=exception.getStackTrace()%></code></pre><br/>
    
    
            <script src="assets/prism/prism.js"></script>
        </body>
    </html>
    

      

    out 对象:

    out 对象代表一个页面输出流,通常用于在页面上输出变量值及常量。一般在使用输出表达式的地方,都可以用 out 对象来达到同样效果。

    如:

    <%@ page contentType="text/html; charset=UTF-8" %>
    <%@ page import="java.sql.*" %>
    
    <html>
        <head>
            <title>out 测试</title>
        </head>
        <body>
    <%
    // 注册数据库驱动
    Class.forName("com.mysql.jdbc.Driver");
    // 获取数据库连接
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp", "root", "root");
    // 创建 Statement 对象
    Statement stmt = conn.createStatement();
    // 执行查询,获得 ResultSet 对象
    ResultSet rs = stmt.executeQuery("select * from person");
    %>
            <table border="1" width="400">
                <%
                // 遍历结果集
                while(rs.next()) {
                    // 输出表格行
                    out.println("<tr>");
                    // 输出表格列
                    out.println("<td>");
                    // 输出结果集第一列的值
                    out.println(rs.getString(1));
                    // 关闭表格列
                    out.println("</td>");
                    // 开始表格列
                    out.println("<td>");
                    // 输出结果集第二列的值
                    out.println(rs.getString(2));
                    // 关闭表格列
                    out.println("</td>");
                    // 关闭表格行
                    out.println("</tr>");
                }
                %>
            </table>
        </body>
    </html>

    所有使用 out 的地方,都可使用输出表达式来代替,而且使用输出表达式更加简洁。

    我们把上面的写法换成输出表达式:

    <%@ page contentType="text/html; charset=UTF-8" %>
    <%@ page import="java.sql.*" %>
    
    <html>
        <head>
            <title>out 测试</title>
        </head>
        <body>
    <%
    // 注册数据库驱动
    Class.forName("com.mysql.jdbc.Driver");
    // 获取数据库连接
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp", "root", "root");
    // 创建 Statement 对象
    Statement stmt = conn.createStatement();
    // 执行查询,获得 ResultSet 对象
    ResultSet rs = stmt.executeQuery("select * from person");
    %>
            <table border="1" width="400">
                <%
                // 遍历结果集
                while(rs.next()) {
                %>
                <tr>
                    <td><%=rs.getString(1)%></td>
                    <td><%=rs.getString(2)%></td>
                </tr>
                <%
                }
                %>
            </table>
        </body>
    </html>

    我们可以明显看到,输出结果集的代码量更少了,并且结构也更加的清晰。

    pageContext 对象

    这个对象代表页面上下文,该对象主要用于访问 JSP 之间的共享数据。使用 pageContext 可以访问 page、request、session、application 范围的变量。

    pageContext 是 PageContext 类的实例,它提供了如下两个方法来访问 page、request、session、application 范围的变量。

    1、getAttribute(String name):取得 page 范围内的 name 属性。

    2、getAttribute(String name, int scope):取得指定范围内的 name 属性,其中 scope 可以是如下 4 个值。

     PageContext.PAGE_SCOPE:对应于 page 范围

     PageContext.REQUEST_SCOPE:对应于 request 范围

     PageContext.SESSION_SCOPE:对应于 session 范围

     PageContext.APPLICATION_SCOPE:对应于 application 范围

    与 getAttribute() 方法对应,PageContext 也提供了两个对应的 setAttribute() 方法,用于将指定变量放入 page、request、session、application 范围内。

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <html>
        <head>
            <title>pageContext</title>
        </head>
        <body>
    <%
    // 使用 pageContext 设置属性,该属性默认在 page 范围内
    pageContext.setAttribute("page", "hello");
    // 使用 request 设置属性,该属性默认在 request 范围内
    request.setAttribute("request", "hello");
    // 使用 pageContext 将属性设置在 request 范围内
    pageContext.setAttribute("request2", "hello", pageContext.REQUEST_SCOPE);
    // 使用 session 将属性设置在 session 范围内
    session.setAttribute("session", "hello");
    // 使用 pageContext 将属性设置在 session 范围内
    pageContext.setAttribute("session2", "hello", pageContext.SESSION_SCOPE);
    // 使用 application 将属性设置在 application 范围内
    application.setAttribute("application", "hello");
    // 使用 pageContext 将属性设置在 application 范围内
    pageContext.setAttribute("application2", "hello", pageContext.APPLICATION_SCOPE);
    %>
            <h3>获取各属性的值</h3>
            <p>page 范围的 page 属性值:<%=pageContext.getAttribute("page")%></p>
            <p>request  范围的 request 属性值:<%=request.getAttribute("request")%></p>
            <p>request  范围的 request2 属性值:<%=request.getAttribute("request2")%></p>
            <p>session 范围的 session 属性值:<%=session.getAttribute("session")%></p>
            <p>session 范围的 session2 属性值:<%=session.getAttribute("session2")%></p>
            <p>application 范围的 application 属性值:<%=application.getAttribute("application")%></p>
            <p>application 范围的 application2 属性值:<%=application.getAttribute("application2")%></p>
        </body>
    </html>
    

      

    request 对象:

    request 对象是 JSP 中重要的对象,每个 request 对象封装着一次用户请求,并且所有的请求参数都被封装在 request 对象中,因此 request 对象是获取请求参数的重要途径。

    1、获取请求头/请求参数

    String getParameter(String paramName):获取 paramName 请求参数的值。

    Map getParameterMap(): 获取所有请求参数名和参数值组成的 Map 对象。

    Enumeration getParameterNames():获取所有请求参数名所组成的 Enumeration 对象。

    String[] getParameterValues(String name):name 请求参数的值,当该请求参数有多个值时,该方法将返回多个值所组成的数组。

    HttpServletRequest 提供了如下方法来访问请求头:

    String getHeader(String name):获取指定请求头的值。

    java.util.Enumeration<String> getHeaderNames():获取所欲请求头的名称。

    java.util.Enumeration<String> getHeaders(String name):获取指定请求头的多个值。

    int getIntHeader(String name):获取指定请求头的值,并将该值转为整数值。

    并不是每个表单域都会生成请求参数,而是有 name 属性的表单域才生成请求参数。关于表单域和请求参数的关系遵循如下四点:

    a、每个有 name 属性的表单域对应一个请求参数。

    b、如果多个表单域有相同的 name 属性,则多个表单域只生成一个请求参数,只是该参数有多个值。

    c、表单域的 name 属性指定请求参数名,value 指定请求参数值。

    d、如果某个表单域设置了 disabled="disabled" 属性,则该表单域不再生成请求参数。

    request示例:

    form.jsp

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <html>
        <head>
            <title>form</title>
        </head>
        <body>
            <form method="POST" action="request1.jsp">
                用户名:<br /><input type="text" name="name"><hr/>
    
                性别:<br />
                男:<input type="radio" name="gender" value="男">
                女:<input type="radio" name="gender" value="女"><hr/>
    
                喜欢的颜色:<br />
                红:<input type="checkbox" name="color" value="红">
                蓝:<input type="checkbox" name="color" value="蓝">
                绿:<input type="checkbox" name="color" value="绿"><hr/>
    
                来自的国家:<br />
                <select name="country">
                    <option value="中国">中国</option>
                    <option value="美国">美国</option>
                    <option value="俄罗斯">俄罗斯</option>
                </select><hr/>
    
                <input type="submit" value="提交">
                <input type="reset" value="重置">
            </form>
        </body>
    </html>
    

      

    request1.jsp

    <%@ page contentType="text/html; charset=UTF-8" %>
    <%@ page import="java.util.*" %>
    
    <html>
        <head>
            <title>获取请求头/请求参数</title>
        </head>
        <body>
    <%
    // 获取所有请求头的名称
    Enumeration<String> headerNames = request.getHeaderNames();
    while(headerNames.hasMoreElements())
    {
        String headerName = headerNames.nextElement();
        // 获取每个请求、及其对应的值
        out.println(headerName + "-->" + request.getHeader(headerName) + "<br />");
    }
    out.println("<hr/>");
    
    // 设置解码方式
    request.setCharacterEncoding("UTF-8");
    // 下面依次获取表单域的值
    String name = request.getParameter("name");
    String gender = request.getParameter("gender");
    // 如果某个请求参数有多个值,将使用该方法获取多个值
    String[] colors = request.getParameterValues("color");
    String nation1 = request.getParameter("country");
    %>
    
        <!-- 下面依次输出表单域的值 -->
        你的名字:<%=name%><hr/>
        你的性别:<%=gender%><hr/>
        <!-- 输出复选框获取的数组值 -->
        你喜欢的颜色:<% for(String c: colors)
        out.println(c + " ");%><hr/>
        你来自的国家:<%=nation1%><hr/>
        </body>
    </html>
    

      

    获取包含非西欧字符的 GET 请求参数:

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <html>
        <head>
            <title>request2</title>
        </head>
        <body>
    <%
    // 获取请求里包含的查询字符串
    String rawQueryStr = request.getQueryString();
    out.println("原始查询字符串为:" + rawQueryStr + "<hr/>");
    // 使用 URLDecoder 解码字符串
    String queryStr = java.net.URLDecoder.decode(rawQueryStr, "UTF-8");
    out.println("解码后的查询字符串为:" + queryStr + "<hr/>");
    // 以 & 号分解查询字符串
    String[] parameterPairs = queryStr.split("&");
    for(String parameterPair : parameterPairs)
    {
        out.println("每个请求参数名、值为:" + parameterPair + "<br />");
        // 以 = 来分解请求参数名和值
        String[] nameValue = parameterPair.split("=");
        out.println(nameValue[0] + "参数的值是:" + nameValue[1] + "<hr>");
    }
    %>
        </body>
    </html>
    

      

    也可以在获取请求参数之后对请求参数值重新编码,也就是先将其转换成字节数组,再将字节数组重新解码成字符串。如:

    // 获取原始的请求参数值
    String rawName = request.getParameter("name");
    // 将请求参数值使用 ISO-8859-1 字符串分解成字节数组
    byte[] rawBytes = rawName.getBytes("ISO-8859-1");
    // 将字节数组重新解码成字符串
    String name = new String(rawBytes, "UTF-8");
    

      

    2、操作 request 范围的属性

    HttpServletRequest 还包含如下两个方法,用于设置和获取 request 范围的属性。

    setAttribute(String attrName, Object attrValue):将 attrValue 设置成 request 范围的属性。

    Object getAttribute(String attrName):获取 request 范围属性。

    当 forward 用户请求时,请求的参数和请求属性都不会丢失。

    3、执行 forward 或 include

    request 还有一个功能就是执行 forward 和 include,也就是代替 JSP 所提供的 forward 和 include 动作指令。前面需要 forward 时都是使用 JSP 的 forward 指令,实际上 request 对象也可以执行 forward。

    HttpServletRequest 类提供了一个 getRequestDispatcher(String path) 方法,其中 path 就是希望 forward 或者 include 的目标路径,该方法返回 RequestDispatcher,该对象提供了如下两个方法:

    a、forward(ServletRequest request, ServletResponse response):执行 forward。

    b、include(ServletRequest request, ServletResponse response):执行 include。

    如下代码可以将 a.jsp 页面 include 到本页面中:

    request.getRequestDispatcher("/a.jsp").forward(request, response);

    如下代码可以将请求 forward 到 a.jsp 页面:

    request.getRequestDispatcher("/a,jsp").forward(request, response);

    注意:使用 request 的 getRequestDispatcher(String path) 方法时,该 path 字符串必须以斜线开头。

    response 对象:

    response 代表服务器对客户端的响应。大部分时候,程序无须使用 response 来响应客户端请求,因为有个更简单的响应对象 -- out,它代表页面输出流,直接使用 out 生成响应更简单。

    但 out 是 JspWriter 的实例,JspWriter 是 Writer 的子类,Writer 是字符流,无法输出非字符内容,假如需要在页面中动态生成一副位图、或者输出一个 PDF 文档,使用 out 作为响应对象将无法完成,此时必须使用 response 作为响应输出。

    1、response 响应生成非字符响应

    对于需要生成非字符响应的情况,就应该使用 response 来响应客户端请求。下面的 JSP 页面将在客户端生成一张图片。response 是 HttpServletResponse 接口的实例,该接口提供了一个 getOutputStream() 方法,该方法返回响应输出字节流。

    如下,输出一张图片:

    img.jsp

    <!-- 通过 contentType 指定响应数据是图片 -->
    <%@ page contentType="image/png" %>
    <%@ page import="java.awt.image.*,javax.imageio.*,java.io.*,java.awt.*" %>
    
    <%
    // 创建 BufferedImage 对象
    BufferedImage image = new BufferedImage(340, 160, BufferedImage.TYPE_INT_RGB);
    // 以 Image 对象获取 Graphics 对象
    Graphics g = image.getGraphics();
    // 使用 Graphics 画图,所画的图将会出现在 image 对象中
    g.fillRect(0, 0, 400, 400);
    // 设置颜色:红
    g.setColor(new Color(255, 0, 0));
    // 画出一段弧
    g.fillArc(20, 20, 100, 100, 30, 120);
    // 设置颜色:绿
    g.setColor(new Color(0, 255, 0));
    // 画出一段弧
    g.fillArc(20, 20, 100, 100, 150, 120);
    // 设置颜色:蓝
    g.setColor(new Color(0, 0, 255));
    // 画出一段弧
    g.fillArc(20, 20, 100, 100, 270, 120);
    // 设置颜色:黑
    g.setColor(new Color(0, 0, 0));
    g.setFont(new Font("Arial Black", Font.PLAIN, 16));
    // 画出三个字符串
    g.drawString("red:climb", 200, 60);
    g.drawString("green:swim", 200, 100);
    g.drawString("blue:jump", 200, 140);
    g.dispose();
    // 将图像输出到页面响应
    ImageIO.write(image, "png", response.getOutputStream());
    %>
    

      

    使用方法 <img src="/img.jsp">

    以上页面的 contentType 指定为 image/png,这表明服务器响应是一张 PNG 图片。接着创建了一个 BufferedImage 对象(代表图像),并获取该 BufferedImage 的 Graphics 对象(代表画笔),然后通过 Graphics 向 BufferedImage 中绘制图形,最后一行代码直接将 BufferedImage 作为响应发送给客户端。

    2、重定向

    重定向是 response 的另外一个用处,与 forward 不同的是,重定向会丢失所有的请求参数和 request 范围属性,因为重定向将生成第二次请求,与前一次请求不在同一个 request 范围内,所以发送一次清的请求参数和 request 范围属性都会丢失。

    HttpServletResponse 提供了一个 sendRedirect(String path) 方法,该方法用于重定向到 path 资源,即重新向 path 资源发送请求。

    如:

    redirect.jsp

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <%
    // 生成页面响应
    out.println("====");
    // 重定向到 redirect-result.jsp 页面
    response.sendRedirect("redirect-result.jsp");
    %>
    

      

    redirect-result.jsp

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <html>
        <head>
            <title>redirect result</title>
        </head>
        <body>
            被重定向的页面<br/>
            name 请求参数的值: <%=request.getParameter("name")%>
        </body>
    </html>
    

      

    我们在第一个页面的链接后面加上一个get请求参数:http://localhost:8080/jsp/redirect.jsp?name=awk,然后我们在重定向的页面会发现获取到的参数却是 null。

    这就说明,我们的 request 里面的参数已经丢失了。

    forward 与 redirect 的三个区别:

    a、执行 forward 后依然是上一次请求,执行 redirect 后生成第二次请求

    b、forward 的目标页面可以访问原请求的参数,因为依然是同一次请求,所有原请求的请求参数、request 范围属性全部存在。redirect 的目标页面不能访问原请求的请求参数、request 范围属性,因为 redirect 产生了一个新的请求。

    c、forward 的时候地址栏 URL 不会发生变化。redirect 的时候地址栏 URL 是 redirect 的时候 sendRedirect 参数的值。

    3、增加 Cookie

     response 对象提供了如下方法:

    void addCookie(Cookie cookie):增加cookie

    增加 cookie 请按如下步骤进行。

    a、创建 Cookie 实例,Cookie 的构造器为 Cookie(String name, String value)

    b、设置 Cookie 的生命期限,即该 Cookie 在多长时间内有效。

    c、向客户端写 Cookie

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <html>
        <head>
            <title>cookie</title>
        </head>
        <body>
    <%
    // 获取请求参数
    String name = request.getParameter("name");
    // 以获取到的请求参数为值,创建一个 Cookie 对象
    Cookie c = new Cookie("username", name);
    // 设置 Cookie 对象的生存期限(这里是 24 小时)
    c.setMaxAge(24 * 3600);
    // 向客户端增加 Cookie 对象
    response.addCookie(c);
    %>
        </body>
    </html>
    

      

    访问客户端的 cookie,request 对象提供了 getCookies 方法,该方法返回客户端机器上所有 Cookie 组成的数组。

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <html>
        <head>
            <title>读取 cookie</title>
        </head>
        <body>
    <%
    // 获取本站在客户端上保留的所有 cookie
    Cookie[] cookies = request.getCookies();
    // 遍历客户端上的每个 Cookie
    for (Cookie c : cookies) {
        // 如果 Cookie 的名为 username,表明该 Cookie 是需要访问的 Cookie
        if (c.getName().equals("username")) {
            out.println(c.getValue());
        }
    }
    %>
        </body>
    </html>
    

      

    默认情况下,Cookie 值不允许出现中文字符,如果需要值为中文内容的 Cookie,我们可以借助于 java.net.URLEncoder 先对中文字符串进行编码,将编码后的结果设置为 Cookie 值。当程序要读取 Cookie 时,则应该先读取,然后使用 java.net.URLDecoder 对其进行解码。

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <html>
        <head>
            <title>中文 Cookie</title>
        </head>
        <body>
    <%
    // 以编码后的字符串为值,创建一个 Cookie 对象
    Cookie c = new Cookie("cnName", java.net.URLEncoder.encode("李白", "utf-8"));
    // 设置 Cookie 对象的生存期限
    c.setMaxAge(24 * 3600);
    // 向客户端增加 Cookie 对象
    response.addCookie(c);
    
    // 获取本站在客户端上保留的所有 Cookie
    Cookie[] cookies = request.getCookies();
    // 遍历客户端上的每个 Cookie
    for (Cookie cookie : cookies) {
        // 如果 Cookie 的名为 cnName,表明该 Cookie 是需要访问的 Cookie
        if (cookie.getName().equals("cnName")) {
            // 使用 java.net.URLDecoder 对 Cookie 值进行解码
            out.println(java.net.URLDecoder.decode(cookie.getValue()));
        }
    }
    %>
        </body>
    </html>
    

      

    session 对象

    session 对象代表一次用户会话。一次用户会话的含义是:从客户端浏览器连接服务器开始,到客户端浏览器与服务器断开为止,这个过程就是一次会话。

    session 范围内的属性可以在多个页面的跳转之间共享。一旦关闭浏览器,即 session 结束,session 范围内的属性将全部丢失。

    session 对象是 HttpSession 的实例,HttpSession 有如下两个常用的方法。

    setAttribute(String attrName, Object attrValue):设置 session 范围内 attrName 属性的值为 attrValue。

    getAttribute(String attrName):返回 session 范围内 attrName 属性的值。

    使用 session 示例:

    shop.jsp

    <%@ page contentType="text/html; charset=UTF-8" %>
    
    <html>
        <head>
            <title>选择物品购买</title>
        </head>
        <body>
            <form method="POST" action="process-buy.jsp">
                书籍:<input type="checkbox" name="item" value="book"/><br/>
                电脑:<input type="checkbox" name="item" value="computer"/><br/>
                汽车:<input type="checkbox" name="item" value="car"/><br/>
                <input type="submit" value="购买" />
            </form>
        </body>
    </html>
    

      

    process-buy.jsp

    <%@ page contentType="text/html; charset=UTF-8" %>
    <%@ page import="java.util.*" %>
    
    <%
    // 取出 session 范围的 itemMap 属性
    Map<String, Integer> itemMap = (Map<String, Integer>)session.getAttribute("itemMap");
    // 如果 Map 对象为空,则初始化 Map 对象
    if (itemMap == null)
    {
        itemMap = new HashMap<String, Integer>();
        itemMap.put("书籍", 0);
        itemMap.put("电脑", 0);
        itemMap.put("汽车", 0);
    }
    // 获取上一个页面的请求参数
    String[] buys = request.getParameterValues("item");
    // 遍历数组的各元素
    for (String item : buys)
    {
        // 如果 item 为 book,表示选择购买书籍
        if (item.equals("book"))
        {
            int num1 = itemMap.get("书籍").intValue();
            // 将书籍 key 对应的数量加 1
            itemMap.put("书籍", num1 + 1);
        }
        else if (item.equals("computer"))
        {
            int num2 = itemMap.get("电脑").intValue();
            itemMap.put("电脑", num2 + 1);
        }
        else if (item.equals("car"))
        {
            int num3 = itemMap.get("汽车").intValue();
            itemMap.put("汽车", num3 + 1);
        }
    }
    
    // 将 itemMap 对象放到 session 范围中
    session.setAttribute("itemMap", itemMap);
    %>
    
    <html>
        <head>
            <title>process buy</title>
        </head>
        <body>
            你购买的物品:<br/>
            书籍:<%=itemMap.get("书籍")%>本<br/>
            电脑:<%=itemMap.get("电脑")%>台<br/>
            汽车:<%=itemMap.get("汽车")%>辆<br/>
            <p><a href="shop.jsp">再次购买</a></p>
        </body>
    </html>
    

      

    关于 session 还有一点需要注意的,session 保存的信息需要保存到 web 服务器的硬盘上,所以要求 session 里的属性值必须是可序列化的,否则将会引发不可序列化的异常。

    session 的属性值可以是任何可序列化的 Java 对象。

  • 相关阅读:
    StringBuffer
    判断java标识符
    基本数据类型和String相互转换
    使用String
    Properties属性文件
    Map排序
    java集合之三映射:HashMap、Hashtable、LinkedHashMap、TreeMap
    列表、集合与数组之间相互转换
    自定义列表排序
    ML-支持向量:SVM、SVC、SVR、SMO原理推导及实现
  • 原文地址:https://www.cnblogs.com/eleven24/p/8605808.html
Copyright © 2011-2022 走看看