1. JSP 概述

1.1 JSP 简介

QQ截图20210412215757.png

  • 是 Servlet 的扩展
  • 是一种基于 Java 的 服务器端技术
  • 目的是简化建立和管理动态网站的工作

    1.2 JSP 特别点

  • 简单快捷

  • 动态内容的生成和显示分离
  • 组件重用
  • 易于部署、升级和维护

    1.3 JSP 与 Servlet 的比较

    image.png
    示例:
    hello-jsp.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. <!DOCTYPE html>
    4. <html>
    5. <head>
    6. <meta charset="UTF-8">
    7. <title>Hello JSP</title>
    8. </head>
    9. <body>
    10. <%
    11. out.print("Hello JSP!");
    12. %>
    13. </body>
    14. </html>
  • 指令:<%@ directive attribute=”value” %> | 指令 | 描述 | | —- | —- | | <%page … %> | 定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等 | | <%@ include … %> | 包含其他文件 | | <%@ taglib … %> | 引入标签库的定义,可以是自定义标签 |

  • 语法:<% 代码片段 %>

    1.4 执行原理

  1. 首次被请求

image.png

  1. 再次被请求

image.png
翻译后的 Java 源码和编译后的字节码文件,都在 Tomcat 目录下的 work 子目录中。

1.5 生命周期

理解 JSP 底层功能的关键就是去理解它们所遵守的生命周期。
JSP 生命周期就是从创建到销毁的整个过程,类似于 Servlet 生命周期,区别在于 JSP 生命周期还包括将 JSP 文件编译成 Servlet。

  • 编译阶段:Servlet 容器编译 Servlet 源文件,生成 Servlet 类。
  • 初始化阶段:加载与 JSP 对应的 Servlet 类,创建其实例,并调用它的初始化方法。
  • 执行阶段:调用与 JSP 对应的 Servlet 实例的服务方法。
  • 销毁阶段:调用与 JSP 对应的 Servlet 实例的销毁方法,然后销毁 Servlet 实例。

三、JSP - 图5

1.6 JSP 编译

当浏览器请求 JSP 页面时,JSP 引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个 JSP 文件。
编译的过程包括三个步骤:

  • 解析 JSP 文件。
  • 将 JSP 文件转为 Servlet。
  • 编译 Servlet。

life-cycle.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP LifeCycle</title>
</head>
<body>
    <%!
      int initVar = 0;
      int serviceVar = 0;
      int destroyVar = 0;
    %>
    <%!
      public void jspInit(){
           initVar++;
           System.out.println("jspInit(): JSP被初始化了" + initVar + "次");
         }
         public void jspDestroy(){
           destroyVar++;
           System.out.println("jspDestroy(): JSP被销毁了" + destroyVar + "次");
         }
       %>
       <%
         serviceVar++;
      System.out.println("_jspService(): JSP共响应了" + serviceVar + "次请求");

      String content1 = "初始化次数 : " + initVar;
      String content2 = "响应客户请求次数 : " + serviceVar;
      String content3 = "销毁次数 : " + destroyVar;
    %>
    <p><%=content1 %></p>
      <p><%=content2 %></p>
      <p><%=content3 %></p>

</body>
</html>

问题:contentType 和 pageEncoding 都有对字符集的设置,两者有什么区别?

2. JSP 指令和动作

2.1 JSP 指令

JSP 指令用来向 JSP 引擎(Tomcat)提供编译信息。

  • page 指令
  • include 指令
  • taglib 指令

    2.1.1 page 指令

  • 用于设置页面的各种属性,如导入包、指明输出内容类型、控制Session等。

  • 一般位于JSP 页面的开头部分,一个 JSP 页面可包含多条 page 指令。 | 属性名 | 说明 | | —- | —- | | language | 设定JSP页面使用的脚本语言。默认为java,目前只可使用java语言 | | extends | 此JSP页面生成的Servlet的父类 | | import | 指定导入的java软件包或类名列表。如果多个类时,中间用逗号隔开 | | session | 设定JSP页面是否使用Session对象。值为“true|false”,默认为true | | buffer | 设定输出流是否有缓冲区。默认为8KB,值为“none | sizekb” | | autoFlush | 设定输出流的缓冲区是否要自动清除。值为“true | false”,默认值为true | | isThreadSafe | 设定JSP页面生成的Servlet是否实现SingleThreadModel接口。值为“true | false”,默认为true | | info | 主要表示此JSP网页的相关信息 | | errorPage | 设定JSP页面发生异常时重新指向的页面URL | | isErrorPage | 指定此JSP页面是否为处理异常错误的网页。值为“true | false”,默认为false | | contentType | 指定MIME类型和JSP页面的编码方式 | | pageEncoding | 指定JSP页面的编码方式 | | isELlgnored | 指定JSP页面是否忽略EL表达式。值为“true | false”,默认值为false |

2.1.1.1 import 属性

  • import属性可以在当前JSP 页面中引入 JSP 脚本代码需要用到的其他类。
  • 如果需要引入多个类或包,可以在中间使用逗号隔开或使用多个page 指令。

page-instruction.jps

<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>page 指令</title>
</head>
<body>
    <p>现在时间:<%=new Date() %></p>
</body>
</html>

对日期进行格式化

<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>page 指令</title>
</head>
<body>
    <%
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    %>
    <p>现在时间:<%=sdf.format(new Date()) %></p>
</body>
</html>

注意:import 是 page 指令中唯一一个可以在同一个 JSP 页面中多次出现的属性。

2.1.1.2 contentTyp 属性

  • contentType 用于指定 JSP 输出内容的MIME 类型和字符集。MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
  • MIME 类型通常由两部分组成:
    • MIME类型
    • MIME 子类型

Snipaste_2021-04-20_06-38-36.png

  • 通过设置contentType 属性,可以改变JSP 输出的 MIME 类型,从而实现一些特殊的功能。

page-excel.jsp

<%@ page language="java" contentType="application/vnd.ms-excel; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP 生成 Excel 表格</title>
</head>
<body>
    <table border="1" cellspacing="0" cellpadding="3">
        <thead>
            <tr>
                <th>姓名</th>
                <th>兵器</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>唐僧</td>
                <td>九环锡杖</td>
            </tr>
            <tr>
                <td>孙悟空</td>
                <td>金箍棒</td>
            </tr>
            <tr>
                <td>猪八戒</td>
                <td>九齿钉耙</td>
            </tr>
            <tr>
                <td>沙僧</td>
                <td>降妖宝杖</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

page-word.jsp

<%@ page language="java" contentType="application/msword; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP 生成 Excel 表格</title>
</head>
<body>
    <table border="1" cellspacing="0" cellpadding="3">
        <thead>
            <tr>
                <th>姓名</th>
                <th>兵器</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>唐僧</td>
                <td>九环锡杖</td>
            </tr>
            <tr>
                <td>孙悟空</td>
                <td>金箍棒</td>
            </tr>
            <tr>
                <td>猪八戒</td>
                <td>九齿钉耙</td>
            </tr>
            <tr>
                <td>沙僧</td>
                <td>降妖宝杖</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

2.1.2 include 指令

  • include 指令用于在当前 JSP 中包含其他文件,被包含的文件可以是 JSP、HTML 或文本文件。
  • 包含的过程发生在将 JSP 翻译成 Servlet 时,当前 JSP 和被包含的 JSP 会融合到一起,形成一个 Servlet,然后进行编译并运行。

include-index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
    <%@ include file="include-header.jsp" %>
    <h1>Hello JSP!</h1>
    <%@ include file="include-footer.jsp" %>
</body>
</html>

include-header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>头部</title>
</head>
<body>
    <h1>Hello Header</h1>
</body>
</html>

include-footer.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>版权</title>
</head>
<body>
    <h1>Hello Footer</h1>
</body>
</html>

2.2 JSP 标准动作

2.2.1 JavaBean 简介

JavaBean实际上就是一种满足特定要求的Java类:

  • 是一个公有类,含有公有的无参构造方法;
  • 属性私有;
  • 属性具有公有的get和set方法。

    2.2.2 JSP 动作

  • 在 JSP 中可以使用 XML 语法格式的一些特殊标记来控制行为,称为 JSP 标准动作(Standard Action)。

  • JSP规范定义了一系列标准动作,常用有下列几种:

    • jsp:useBean:查找或者实例化一个 JavaBean;
    • jsp:setProperty:设置 JavaBean 的属性;
    • jsp:getProperty:输出某个 JavaBean 的属性;
    • jsp:include:在页面被请求时引入一个文件;
    • jsp:forward:把请求转发到另一个页面。

      2.2.2.1

      useBean标准动作用来查找或者实例化一个JavaBean。
      <jsp:useBean id="name" class="className" scope="scope" />
      <jsp:useBean id="name" type="className" scope="scope" />
      
  • id:指定该 JavaBean 实例的变量名,通过 id 可以访问这个实例。

  • class:指定 JavaBean 的类名。如果需要创建一个新的实例,容器会使用 class 指定的类并调用无参构造方法来完成实例化。
  • scope 指定 JavaBean 的作用范围。可以使用四个值:page、request、session 和 application。

    • page(缺省值):表明此 JavaBean 只能应用于当前页;
    • request:表明此 JavaBean 只能应用于当前的请求;
    • session:表明此 JavaBean 能应用于当前会话;
    • application:则表明此 JavaBean 能应用于整个应用程序内。

      2.2.2.2

      setProperty标准动作用于设置JavaBean中的属性值。
      <jsp:setProperty name="id" property="属性名" value="值"/>
      <jsp:setProperty name="id" property="属性名" param="参数名"/>
      
  • name:指定JavaBean对象名,与useBean标准动作中的id相对应;

  • property:指定JavaBean中需要赋值的属性名;
  • value:指定要为属性设置的值;
  • param:指定请求中的参数名(该参数可以来自表单、URL传参数等),并将该参数的值赋给property所指定的属性。

    2.2.2.3

    getProperty标准动作用于访问一个bean的属性并将其输出。访问所得到的值将转换成String类型。

    <jsp:getProperty name="id" property="属性名"/>
    
  • name:指定JavaBean对象名,与useBean标准动作中的id相对应;

  • property:指定JavaBean中需要访问的属性名。

User.java

package cn.cyber.entity;

public class User {
    public User() {
        super();
        System.out.println("Constructor()...");
    }

    public User(String username, String password) {
        super();
        this.username = username;
        this.password = password;
    }

    private String username;
    private String password;
    public String getUsername() {
        System.out.println("getUsername()...");
        return username;
    }
    public void setUsername(String username) {
        System.out.println("setUsername()...");
        this.username = username;
    }
    public String getPassword() {
        System.out.println("getPassword()...");
        return password;
    }
    public void setPassword(String password) {
        System.out.println("setPassword()...");
        this.password = password;
    }
}

login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
    <form action="login.jsp" method="post">
        <div>
            <label for="uname">Username: </label>
            <input type="text" id="uname" name="user_name">
        </div>
        <div>
            <label for="upwd">Password: </label>
            <input type="password" id="upwd" name="pass_word">
        </div>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <!-- 实例化一个 JavaBean(Java 类) -->
    <!-- 
        User user = new User();
     -->
    <jsp:useBean id="user" class="cn.cyber.entity.User" scope="request"></jsp:useBean>

    <!-- 对实例化后的 JavaBean 进行初始化,即对属性进行赋值 -->
    <!-- 
        user.setUsername(request.getParamenter("user_name"));
        user.setPassword(request.getParamenter("pass_word"));
     -->
    <jsp:setProperty name="user" property="username" param="user_name"/>
    <jsp:setProperty name="user" property="password" param="pass_word"/>

    <!-- 展示已经实例化的 JavaBean 的属性值 -->
    <!-- 
        user.getUsername("username");
        user.getPassword("password");
     -->
    <p>Username: <jsp:getProperty name="user" property="username"/></p>
    <p>Password: <jsp:getProperty name="user" property="password"/></p>
</body>
</html>

2.2.2.4

  • include 标准动作用于在 JSP 页面动态包含其他页面。
  • 该动作的功能与 JSP 的 include 指令类似,区别是 include 指令在编译时完成包含,是静态包含(一共只有一个文件);而 include 标准动作是在运行时完成包含,是动态包含(有 N 个 JSP 文件,则有 N 个 Java 文件,同时,有 N 个 class 文件)。

语法如下:

<jsp:include page="被包含文件的URL" />

如果需要额外的请求参数,则需要使用

<jsp:include page="被包含文件的URL">
  <jsp:param name="参数名" value="参数值" />
</jsp:include>

对之前的 include-index.jsp 进行改造:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
    <!--  
    <%@ include file="include-header.jsp" %>
    -->
    <jsp:include page="include-header.jsp"></jsp:include>
    <h1>Hello JSP!</h1>
    <jsp:include page="include-footer.jsp"></jsp:include>
    <!-- 
    <%@ include file="include-footer.jsp" %>
    -->
</body>
</html>

查看 Tomcat 的 work 子目录
Snipaste_2021-04-24_23-45-15.png

2.2.2.5

forward 标准动作用于将用户的请求转发到另一个 HTML 文件、JSP 页面或 Servlet,语法格式如下:

<jsp:forward page="URL地址" />

如果需要额外的请求参数,则需要使用

<jsp:forward page="被包含文件的URL">
  <jsp:param name="参数名" value="参数值" />
</jsp:forward>

注意:forward 动作与 RequestDispatcher 类型对象的 forward 方法类似,调用者和被调用者共享同一个 request 对象。

2.2.2.6

param 标准动作用于为其他动作标签提供附加参数值信息,该动作可以与 等一起使用,其语法格式如下:

<jsp:param name="参数名" value="参数值" />

例如:

<jsp:include page="show.jps">
  <jsp:param name="username" value="admin" />
</jsp:include>

上述代码中,在 include 标准动作中使用 设置了参数,这样在 show.jsp 页面中就可以用 request 对象的 getParameter() 方法取得这两个参数。
测试

本题目共涉及4个文件: 1.login.html:登录页面,提交用户名和密码给 login.jsp。 2.login.jsp:实例化 JavaBean 并进行初始化,然后使用 JSP 标准动作转发到 index.jsp。 3.index.jsp:使用 JavaBean,显示用户名和密码;使用 JSP 标准动作包含 header.jsp 页面。 4.header.jsp:打印“Hello XXX”(XXX 为用户名)。

3. JSP 内置对象

3.1 内置对象概述

JSP 内置对象:由 JSP 容器(Tomcat)加载,不需要声明就可以直接在 JSP 页面中使用的对象。
JSP 九大内置对象

名称 说明
request 客户端的请求,包含所有从浏览器发往服务器的请求信息
response 返回客户端的响应
session 会话对象,表示用户的会话状态
application 应用上下文对象,作用于整个应用程序
out 输出流,向客户端输出数据
pageContext 用于存储当前 JSP 页面的相关信息
config JSP 页面的配置信息对象
page 表示 JSP 页面的当前实例
exception 异常对象,用于处理 JSP 页面中的错误

3.2 常用内置对象

3.2.1 out 对象

out 对象是一个输出流,用于将信息输出到网页中。常用得方法:

  • print()
  • println()
  • writer()

三者都是输出信息,有区别么?
out.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>out 对象</title>
</head>
<body>
    <%
      out.print("Hello Print");
      out.println("Hello Println");
      out.write("Hello Write");
    %>
</body>
</html>
  • println() 虽然看似是换行,但转成网页之后,这种换行被认为是空格,所以输出的内容仍然在同一行,用空格分隔。
  • print() 和 println() 是 JspWriter 类中定义的方法,write() 则是 Writer 类中定义的。
  • print() 和 println() 方法可将各种类型的数据转换成字符串的形式输出,而 write() 方法只能输出字符、字符数组和字符串等与字符相关的数据。
  • 如果字符串对象的值为 null,print() 和 println() 方法将输出内容为“null”的字符串,而 write() 方法则是抛出 NullPointerException 异常。

Student.java

package cn.cyber.entity;

public class Student {
    private String stuNo;
    private int age;
    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(String stuNo, int age) {
        super();
        this.stuNo = stuNo;
        this.age = age;
        System.out.println("Student Constructor...");
    }
    public String getStuNo() {
        return stuNo;
    }
    public void setStuNo(String stuNo) {
        this.stuNo = stuNo;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [stuNo=" + stuNo + ", age=" + age + "]";
    }
}

out.jsp

<%@page import="cn.cyber.entity.Student"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>out 对象</title>
</head>
<body>
    <%
      out.print("Hello Print");
      out.println("Hello Println");
      out.write("Hello Write");
      Student student = new Student("111", 20);
      out.print(student);
      out.println(student);
      // out.write(student);
      String text = null;
      out.print(text);
      out.println(text);
      try{
          out.write(text);
      } catch(Exception e){
          e.printStackTrace();
          out.print(e.getMessage());
          out.print("text=null");
      }
    %>
</body>
</html>

除了用于输出数据的上述三种方法外,out 对象中还拥有其他常用方法:

  • clear():清除缓冲区的内容,如果缓冲区已经被刷出(flush),将抛出 IOException。
  • clearBuffer():清除缓冲区的当前内容,和 clear() 方法不同,即使缓冲区已经 flush,也不会发生异常。
  • flush():输出缓冲区中的内容。
  • close():关闭输出流,清除所有内容。

    3.3.2 request 对象

    request 对象是r HttpServletRequest 接口实现类的实例。包含所有从浏览器发往服务器的请求信息,例如请求的来源、Cookie 和客户端请求相关的数据。
    request 对象中最常用得方法如下:

  • String getParameter(String name):根据参数名称得到单一参数值;

  • String[] getParameterValues(String name):根据参数名称得到一组参数值;
  • void setAttribute(String name, Object value):以名/值的方式存储数据;
  • Object getAttribute(String name):根据名称得到存储的数据。

注意

  • 对于复选框 checkbox,需要先判断其数组是否为 null,再进行遍历,因为如果用户没有选择任何选项,则 getParameterValues() 返回 null。
  • 对于普通文本框 text,当没有任何输入信息时,浏览器仍然提交该表单元素信息,这时再服务器端通过 getParameter() 获取表单值时,结果为空字符串””。
  • 对于单选框 radio 或复选框 checkbox,当没有任何选择时,浏览器不会提交该表单元素信息,因此再服务器端获取该表单元素信息时为 null。
  • 并不是每个文本框都会生成请求参数,而是有 name 属性得文本框才生成请求参数,即每个有 name 属性得文本框对应一个请求参数。
  • 如果文本框配置了 disabled=”disabled”属性,则相应表单提交数据时不会提交该文本框信息。
  • 除文本框外,其他表单元素亦如此。

    3.3.3 response 对象

    response 对象是 HttpServletResponse 接口实现类的实例,负责将响应结果发送到浏览器端。
    response 常用的方法如下:

  • void setContentType(String name):设置响应内容的类型和字符编码;

  • void sendRedirect(String url):重定向到指定的 URL 资源。

    3.3.4 session 对象

    session 对象是 HttpSession 接口实现类的实例,表示用户的会话状态。
    session 常用的方法如下:

  • void setAttribute(String name, Object value):以名/值的方式存储数据;

  • Object getAttribute(String name):根据名称得到存储的数据。

    3.3.5 application 对象

    application 对象是 ServletContext 接口实现类的实例,其作用于整个应用程序,由应用程序中的所有 Servlet 和 JSP 页面共享。
    application 常用的方法如下:

  • void setAttribute(String name, Object value):以名/值的方式存储数据;

  • Object getAttribute(String name):根据名称得到存储的数据。

    3.3.6 page 对象

    page 对象表示 JSP 页面的当前实例,实际上相当于 this,可以提供对 JSP 页面上定义的所有对象的访问。实际开发中很少使用 page 对象。

    3.3.7 pageContext 对象

    pageContext 对象可以访问当前 JSP 页面所有的内置对象,如 request、response、session、application、out等。pageContext 对象还提供存取数据的方法,作用范围为当前 JSP 页面。
    pageContext 常用方法如下:

  • void setAttribute(String name, Object value):以名/值方式存储数据;

  • Object getAttribute(String name):根据名称得到存储的数据。

    <%@ page language="java" contentType="text/html; charset=UTF-8"
      pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
      <%
        if(pageContext.getAttribute("pageCount") == null){
            pageContext.setAttribute("pageCount", 0);
        }
        if(request.getAttribute("requestCount") == null){
            request.setAttribute("requestCount", 0);
        }
        if(session.getAttribute("sessionCount") == null){
            session.setAttribute("sessionCount", 0);
        }
        if(application.getAttribute("applicationCount") == null){
            application.setAttribute("applicationCount", 0);
        }
      %>
      <%
        // page 计数
        int pageCount = Integer.parseInt(pageContext.getAttribute("pageCount").toString());
        pageCount++;
        pageContext.setAttribute("pageCount", pageCount);
        // request 计数
        int requestCount = Integer.parseInt(request.getAttribute("requestCount").toString());
        requestCount++;
        request.setAttribute("requestCount", requestCount);
        // session 计数
        int sessionCount = Integer.parseInt(session.getAttribute("sessionCount").toString());
        sessionCount++;
        session.setAttribute("sessionCount", sessionCount);
        // application 计数
        int applicationCount = Integer.parseInt(application.getAttribute("applicationCount").toString());
        applicationCount++;
        application.setAttribute("applicationCount", applicationCount);
      %>
      <p>page 计数:<%=pageContext.getAttribute("pageCount") %></p>
      <p>request 计数:<%=request.getAttribute("requestCount") %></p>
      <p>session 计数:<%=session.getAttribute("sessionCount") %></p>
      <p>application 计数:<%=application.getAttribute("applicationCount") %></p>
    </body>
    </html>
    

    JSP 的四大作用域:pageContext、request、session、application。

  • 这四个对象都是通过 setAttribute(String name, Object value) 方法来保存数据的,通过 getAttribute(String name) 方法获得数据的。

  • 开发中要根据实际情况选择合适的范围,尽量使用小的范围,因为越大的范围其生命周期越长,相应的就会占用更多的服务器资源。

    3.3.8 config 对象

    config 对象用来存放 Servlet 的一些初始化信息,常用方法如下:

  • String getInitParameter(String name):返回指定名称的初始参数值。

  • Enumeration getInitParameterNames():返回所有初始参数的名称集合。
  • ServletContext getServletContext():返回 Servlet 上下文。
  • String getServletName():返回 Servlet 的名称。

    3.3.9 exception 对象

    exception 对象表示 JSP 页面中的异常信息。需要注意的是,要使用 exception 对象,必须将此 JSP 中 page 指令的 isErrorPage 属性值设置为 true。