JSP 生命周期
什么是 JSP 生命周期?
JSP 生命周期定义为 JSP 页面转换为 servlet,因为 JSP 页面需要先转换为 servlet 才能处理服务请求。生命周期始于 JSP 的创建,终于 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页面的翻译:
A Java servlet 文件由 JSP 源文件生成。这是 JSP 生命周期的第一步。在翻译阶段,容器验证 JSP 页面和标记文件的语法正确性。
- JSP 容器解释该 JSP 页面中使用的标准指令和动作,以及引用标记库的自定义动作(它们都是 JSP 页面的一部分,将在后面的部分中讨论)。
- 在上述图示描述中,第一步将 demo.jsp 翻译为 demo_jsp.java
- 我们以“demo.jsp”为例,如下所示:
演示.jsp
<html> <head> <title>Demo JSP</title> </head> <% int demvar=0;%> <body> Count is: <% Out.println(demovar++); %> <body> </html>
Demo.jsp 代码说明
代码行 1:html 开始标签
代码行 2:头标签
代码行 3 – 4:标题标签,即演示 JSP 和结束头标签
代码行 5 – 6:Scriptlet 标签,其中初始化变量 demo
代码行 7 – 8:在 body 标签中,要在输出中打印的文本(计数为:)
代码行9: Scriplet 标签尝试打印带有递增值的变量 demovar
代码行 10 – 11: 正文和 HTML 标签已关闭
在下面的代码中,演示 JSP 页面被转换为 demo_jsp servlet。
Demo_jsp.java代码解释
代码行 1:Servlet 类 demo_jsp 正在扩展父类 HttpServlet
代码行 2 – 3:重写 jsp 的服务方法,即 _jspservice,其参数为 HttpServletRequest 和 HttpServletResponse 对象
代码行 4: 打开方法
代码行 5:调用方法 getWriter()
响应对象获取 PrintWriterobject(将对象的格式化表示打印到文本输出流)
代码行 6:调用响应对象的setContentType方法设置内容类型
代码行 7:使用 write()
PrintWriter 对象的方法尝试解析 html
代码行 8:将 demovar 变量初始化为 0
代码行 9:呼叫 write()
PrintWriter 对象的方法来解析文本
代码行 10:呼叫 print()
PrintWriter 对象的方法将变量 demovar 从 0+1=1 增加。因此,输出将为 1
代码行 11:使用 write()
PrintWriter 对象的方法尝试解析 html
输出:
- 在这里你可以看到,在截图中 theOutput 是 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请求,它还包含服务方法。
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 页面在其生命周期内提出的所有请求调用该方法- 对于这个阶段,它必须经过上述所有阶段,然后才能调用服务方法。
- 它传递请求和响应对象
- 此方法无法被覆盖
- 该方法如上所示:它负责生成所有 HTTP 方法,即 GET、POST 等。
7)摧毁
public void _jspdestroy() { //all clean up code }
_jspdestroy()
方法也由容器调用- 当容器决定不再需要 servlet 实例来服务请求时,将调用此方法。
- 当调用 destroy 方法时,servlet 已准备好进行垃圾回收
- 这就是生命周期的结束。
- 我们可以覆盖
jspdestroy()
当我们执行任何清理操作(例如释放数据库连接或关闭打开的文件)时,都会使用该方法。