摘要:本文介绍了JSP的基本概念、生命周期、语法、指令和动作,以及常用的九个隐式对象和四个域对象。
环境
Windows 10 企业版 LTSC 21H2
Java 1.8
Tomcat 8.5.50
1 概述
1.1 简介
JSP(Java Server Pages)就是运行在Java服务器中的动态页面,其本质是一个Servlet应用。
JSP是一种跨平台的动态网页技术标准,其主要构成有HTML网页代码、Java代码片段、JSP指令、JSP动作等几部分。
相比于HTML页面,JSP最直观的功能是可以在页面中使用变量,这些变量一般都是从域对象中获取,变量可以使页面动态的显示信息。
JSP更加善于处理显示页面,Servlet更擅长处理业务逻辑,两种技术各有专长,所以一般我们会将Servlet和JSP结合使用,Servlet负责业务,JSP负责显示。
1.2 本质
JSP页面本质上是一个Servlet程序,在第一次访问页面的时候,Servlet容器会将JSP页面转换为Servlet文件,然后再将Java文件编译为字节码文件。
对于index.jsp页面,在Tomcat的工作目录下能看到转换后的文件:
jsp
├── index_jsp.class
└── index_jsp.java
打开Java文件:
1 | public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase |
可以看到JSP页面生成的Servlet继承自HttpJspBase抽象类,然后HttpJspBase抽象类继承了HttpServlet抽象类。
2 生命周期
JSP生命周期就是从创建到销毁的整个过程,类似于Servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成Servlet的过程。
2.1 编译阶段
JSP页面第一次被访问时,容器会将JSP页面转换为Servlet文件,然后再编译为字节码文件。
包括三个步骤:
- 解析JSP页面。
- 将JSP页面转换为Servlet文件。
- 将Servlet文件编译为字节码文件。
2.2 初始化阶段
容器载入JSP文件后,会在执行服务前调用jspInit()方法。如果需要执行自定义的JSP初始化任务,可以重写jspInit()方法。
在JSP页面重写初始化方法:
1 | <%! |
2.3 执行阶段
容器在执行JSP页面时,会调用_jspService()方法。
2.4 销毁阶段
当容器销毁JSP页面时,会调用jspDestroy()方法。如果需要执行自定义的JSP销毁任务,可以重写jspDestroy()方法。
在JSP页面重写销毁方法:
1 | <%! |
3 语法
3.1 声明
声明中的内容会被直接写到类中,因此可以在声明中定义方法和变量。
示例:
1 | <%! |
3.2 脚本片段
脚本片断中的Java代码将被原封不动地搬移进转换后的_jspService()方法中,因此需要遵循方法的书写规范。
也可以直接使用JSP提供的隐式对象来完成Web应用程序特有的功能。
示例:
1 | <% |
3.3 表达式
表达式会被转为成String字符串,然后插入到表达式出现的位置。
示例:
1 | <%= "test" %> |
3.4 注释
注释的内容只在当前JSP页面中可见,在转换后的Servlet中以及浏览器端显示的页面中都是不可见的。
示例:
1 | <%-- 注释 --%> |
4 指令
指令用于设置JSP页面的属性,并不直接产生可见的输出,只是告诉引擎如何处理JSP页面。
语法:
1 | <%@ 指令名称 属性1="值1" 属性2="值2" ... %> |
4.1 page
用于告诉JSP引擎如何解析当前页面,同一个页面可以有多个page指令,通常位于JSP页面的顶端。
常用属性:
| 属性名 | 作用 | 取值 |
|---|---|---|
| language | 设置JSP页面使用的脚本语言 | 脚本语言,默认为java |
| import | 设置页面程序代码使用的类,使用逗号分隔 | 全类名 |
| contentType | 设置服务器发给客户端的内容编码 | 类型和编码方式,默认为text/html; UTF-8 |
| pageEncoding | 设置JSP页面的字符编码 | 字符编码,默认为UTF-8 |
| session | 设置当前页面的session内置对象是否可用 | 默认为true表示session可用,设置为false表示session不可用 |
| errorPage | 设置错误页面地址,跳转时地址栏不改变 | 错误页面地址 |
| isErrorPage | 设置当前页面是否为错误处理页面,设置当前页面的exception内置对象是否可用 | 默认为false表示不是错误处理页面,并且页面的exception内置对象不可用 |
| isELIgnored | 设置是否忽略EL表达式 | 默认为false表示不忽略 |
| isThreadSafe | 设置当前页面是否是线程安全的 | 默认为true表示线程安全 |
| autoFlush | 设置当前页面是否自动刷新输出流 | 默认为true表示自动刷新输出流 |
| buffer | 设置out对象的缓冲区的大小 | 默认为8KB |
4.2 include
用于包含其他JSP页面。
这种方式称为静态引入,Java虚拟机不会单独编译包含的JSP页面,而是将整个页面作为整体进行编译,最终生成一个Java文件。
常用属性:
| 属性名 | 作用 | 取值 |
|---|---|---|
| file | 设置包含的JSP页面路径,可以是绝对路径或相对路径 | 页面路径 |
4.3 taglib
用于引入自定义标签库。
常用属性:
| 属性名 | 作用 | 取值 |
|---|---|---|
| url | 设置标签库的名称空间 | 名称空间 |
| prefix | 设置标签库的前缀,用于在JSP页面中使用标签 | 前缀 |
5 动作
JSP动作与HTML标签不同,HTML标签由浏览器来解析,而JSP动作需要服务器来运行。
语法:
1 | <jsp:动作名称 属性1="值1" 属性2="值2" .../> |
5.1 jsp:include
用于把另外JSP页面的输出内容插入进当前JSP页面的输出内容之中。
这种方式称为动态引入,Java虚拟机会单独编译包含的JSP页面,最终生成多个Java文件。
常用属性:
| 属性名 | 作用 | 取值 |
|---|---|---|
| page | 指定被引入资源的相对路径,可以通过表达式获取 | 相对路径 |
| flush | 指定在插入其他资源的输出内容时,是否先将当前JSP页面已输出的内容刷新到客户端 | 默认为true表示刷新 |
5.2 jsp:forward
用于将请求转发到其他资源。
常用属性:
| 属性名 | 作用 | 取值 |
|---|---|---|
| page | 指定被转发的资源的相对路径,可以通过表达式获取 | 相对路径 |
5.3 jsp:param
用于设置请求参数。
常用属性:
| 属性名 | 作用 | 取值 |
|---|---|---|
| name | 指定参数名称 | 参数名称 |
| value | 指定参数值,可以通过表达式获取 | 参数值 |
5.4 jsp:useBean
用于在指定的域范围中获取指定类型的JavaBean对象。
常用属性:
| 属性名 | 作用 | 取值 |
|---|---|---|
| id | 指定JavaBean对象的名称 | 对象名称 |
| class | 指定JavaBean对象的类型,必须是全限定类名 | 全类名 |
| scope | 指定JavaBean对象的域范围 | 域范围,默认为page |
5.5 jsp:getProperty
用于获取JavaBean对象的属性值。
常用属性:
| 属性名 | 作用 | 取值 |
|---|---|---|
| name | 指定JavaBean对象的名称 | 对象名称,与jsp:useBean动作的id属性相同 |
| property | 指定JavaBean对象的属性名称 | 属性名称 |
5.6 jsp:setProperty
用于设置JavaBean对象的属性值。
常用属性:
| 属性名 | 作用 | 取值 |
|---|---|---|
| name | 指定JavaBean对象的名称 | 对象名称,与jsp:useBean动作的id属性相同 |
| property | 指定JavaBean对象的属性名称 | 属性名称 |
| value | 指定JavaBean对象的属性值,可以通过表达式获取 | 属性值 |
| param | 指定使用哪个请求参数作为JavaBean对象的属性值 | 请求参数 |
指定JavaBean对象的属性值时,只能在value属性和param属性中选择一种,并且只有在新建JavaBean对象时才执行jsp:setProperty动作。
6 隐式对象
隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。隐式对象也被称为内置对象。
JSP内置的九大隐式对象:
- request:HttpServletRequest接口的实例,用于封装客户端请求信息。
- response:HttpServletResponse接口的实例,用于封装服务器响应信息。
- session:HttpSession接口的实例,用于封装用户会话信息。
- application:ServletContext接口的实例,用于封装Web应用程序的信息。
- out:JspWriter接口的实例,用于向客户端输出内容。
- pageContext:PageContext接口的实例,用于封装当前页面的信息。
- config:ServletConfig接口的实例,用于封装当前页面的配置信息。
- page:Object类型的实例,用于封装当前页面的信息。
- exception:Throwable类型的实例,用于封装当前页面的异常信息。
7 域对象
域对象可以在不同的Web资源之间共享数据。
域对象有四个:
- page域:当前页面范围的域对象,对应的是pageContext对象。
- request域:请求范围的域对象,对应的是request对象。
- session域:会话范围的域对象,对应的是session对象。
- application域:应用程序范围的域对象,对应的是application对象。
域对象都有以下三个方法:
1 | // 设置属性名和属性对象 |
条