JSP 生命周期
什么是JSP生命周期?
JSP生命周期是指JSP页面被翻译成Servlet的过程,因为JSP页面需要先转换成Servlet才能处理服务请求。生命周期从JSP的创建开始,到其被销毁结束。
JSP生命周期的不同阶段
当浏览器请求一个JSP页面时,JSP引擎首先检查是否需要编译该页面。如果JSP页面是最后编译的,或者最近在JSP页面中进行了修改,那么JSP引擎就会编译该页面。
JSP页面的编译过程涉及三个步骤
- JSP解析
- 将JSP转换为Servlet
- 编译Servlet
JSP生命周期图
JSP生命周期如下图所示。
以下步骤解释了JSP的生命周期
- JSP页面翻译
- JSP页面编译(JSP页面编译成_jsp.java)
- 类加载(_jsp.java被转换为类文件_jsp.class)
- 实例化(创建生成Servlet的对象)
- 初始化(容器调用
_jspinit()
方法) - 请求处理(容器调用
_jspservice()
方法) - 销毁(容器调用
_jspDestroy()
方法)
下面对上述各点进行更详细的总结。
1) JSP页面翻译
一个 Java Servlet 文件由一个 JSP 源文件生成。这是JSP生命周期的第一步。在翻译阶段,容器会验证JSP页面和标签文件的语法正确性。
- JSP容器会解释标准指令和动作,以及引用标签库的自定义动作(这些都是JSP页面的一部分,将在后面的部分讨论)。
- 在上图的描述中,demo.jsp在第一步被翻译成demo_jsp.java。
- 让我们以“demo.jsp”为例,如下所示:
Demo.jsp
<html> <head> <title>Demo JSP</title> </head> <% int demvar=0;%> <body> Count is: <% Out.println(demovar++); %> <body> </html>
Demo.jsp的代码说明
代码行 1: html开始标签
代码行 2: Head标签
代码行 3-4: Title标签,即Demo JSP,以及关闭的head标签
代码行 5-6: 脚本let标签,在此初始化变量demo
代码行 7-8: 在body标签中,是要在输出中打印的文本(Count is: )
代码行 9: 脚本let标签,尝试打印变量demovar及其递增值
代码行 10-11: Body和HTML标签已关闭
Demo JSP页面在以下代码中转换为demo_jsp servlet。
Demo_jsp.java的代码说明
代码行 1: Servlet类demo_jsp继承自父类HttpServlet
代码行 2-3: 重写jsp的service方法,即_jspservice,它以HttpServletRequest和HttpServletResponse对象作为参数
代码行 4: 方法开始
代码行 5: 调用response对象的getWriter()
方法获取PrintWriter对象(将对象的格式化表示打印到文本输出流)
代码行 6: 调用response对象的setContentType方法设置内容类型
代码行 7: 使用PrintWriter对象的write()
方法尝试解析html
代码行 8: 初始化demovar变量为0
代码行 9: 调用PrintWriter对象的write()
方法解析文本
代码行 10: 调用PrintWriter对象的print()
方法将变量demovar从0递增到0+1=1。因此,输出将是1
代码行 11: 使用PrintWriter对象的write()
方法尝试解析html
输出
- 您可以在截图中看到,输出是1,因为demvar被初始化为0,然后递增到0+1=1。
在上面的示例中,
- demo.jsp是一个初始化和递增变量的JSP。此JSP已转换为servlet(demo_jsp.class),其中JSP引擎加载JSP页面并将其转换为servlet内容。
- 当转换发生时,所有模板文本都会被转换为
println()
语句,所有JSP元素都会被转换为Java代码。
这就是一个简单的JSP页面如何被翻译成一个servlet类。
2) JSP页面编译
- 生成的java servlet文件被编译成java servlet类。
- 从Java源页面到其实现类的翻译可以在JSP页面部署到容器和处理JSP页面之间的任何时间发生。
- 在上图的描述中,demo_jsp.java被编译成类文件demo_jsp.class。
3) 类加载
- 已从JSP源加载的Servlet类现在已加载到容器中。
4) 实例化
- 在此步骤中,将生成类对象,即类的实例。
- 容器在响应请求和其他事件时管理该类的一个或多个实例。通常,JSP容器是使用Servlet容器构建的。JSP容器是Servlet容器的扩展,因为两个容器都支持JSP和Servlet。
- 容器提供的JSPPage接口提供了
init()
和destroy()
方法。 - 有一个HttpJSPPage接口,用于服务HTTP请求,它还包含service方法。
5) 初始化
public void jspInit() { //initializing the code }
_jspinit()
方法将初始化从JSP生成的Servlet实例,并在该阶段由容器调用。- 一旦实例创建完毕,init方法将立即被调用。
- 此方法在JSP生命周期中仅调用一次,初始化方法声明如上所示。
6) 请求处理
void _jspservice(HttpServletRequest request HttpServletResponse response) { //handling all request and responses }
_jspservice()
方法在JSP生命周期中由容器为JSP页面引发的所有请求调用。- 对于此阶段,它必须经历所有上述阶段,然后才能调用service方法。
- 它传递请求和响应对象。
- 此方法不能被重写。
- 如上所示的方法:它负责生成所有HTTP方法,即GET、POST等。
7) 销毁
public void _jspdestroy() { //all clean up code }
_jspdestroy()
方法也由容器调用。- 当容器决定不再需要Servlet实例来服务请求时,就会调用此方法。
- 调用destroy方法后,Servlet就可以进行垃圾回收了。
- 这是生命周期的结束。
- 当我们需要执行任何清理操作时(例如释放数据库连接或关闭打开的文件),我们可以重写
jspdestroy()
方法。