JSP技术模型(二)JSP页面生命周期

来源:互联网 发布:mac上玩qq游戏 编辑:程序博客网 时间:2024/05/16 10:05

一、JSP页面的两个要点

1、JSP页面也是Servlet

JSP页面尽管从结构上看类似于HTML页面,但他实质上是作为Servlet运行。当JSP页面被访问时,容器解析JSP页面并转换成相应的Java文件,该文件申明了一个Servlet类,其成员直接映射到JSP文件的元素上。接下来,容器编译该类并将其装入内存,然后与其他Servlet一样执行并将其输出结果发送到客户端。

2、理解转换单元

在JSP页面中可以使用include指令把另一个文件(如JSP页面、HTML页面等)的内容包含到当前到当前页面中。容器在为当前JSP页面产生Java代码时,它也被包含的文件的内容插入到产生的Servlet中。这些被转换成单个Servlet类的页面集合称为转换单元。有些JSP标签影响整个转换单元而不只是他们所在的页面。

(1)、page指令影响整个转换单元。

(2)、在一个转换单元中一个变量不能多次声明。例如一个变量在主页面中申明了,就不能在被包含的页面中申明。

(3)、在一个转换单元中不能使用<jsp:userBean>动作对一个bean申明两次。

二、JSP生命周期阶段

1、页面转换:对页面解析并创建一个包含对应Servlet的Java源文件;

2、页面编译:对Java源文件编译;

3、加载类:将编译后的类加载到容器中;

4、创建实例:创建一个Servlet实例;

5、调用jspInit()方法:调用其他方法之前用该方法初始化;

6、调用_jspService()方法:对每个请求调用一次该方法;

7、调用jspDestroy()方法:当Servlet容器决定停止Servlet服务器时调用该方法。

(1)、创建Servlet实例

[1]、转换阶段:在转换阶段,容器解读JSP页面对其解析,并将其转换成Java源代码。在这个阶段,容器需要检查JSP页面所使用的标签的语法、指令中属性/值对与标准动作的合法性、同一个JavaBeans名称在一个转换单元中没有被多次使用、使用的自定义标签以及用法是否合法,如果发现错误将不能转换。

一旦验证完成,容器将创建一个public的包含Servlet类的Java源文件。该文件位于<CATALINA_HOME>\work\Catalina\localhost\helloapp\org\apache\jsp目录中,它包含对应于JSP文件的Servlet。

[2]、编译阶段:在将JSP页面转换成Java文件后,容器调用java编译器javac编译改文件。在该阶段,编译器将检查在申明中、小脚本中以及表达式中所写的全部Java代码。

[3]、转载与实例化:编译成功后,容器将Servlet类装入内存并实例化之。

(2)、调用JSP生命周期方法

JSP页面产生的Servlet类实现了javax.servlet.jsp.HttpJspPage接口。HttpJspPage接口扩展了同一个包中的JspPage接口,该接口又扩展了javax.servlet包中的Servlet接口。因此,JSP页面产生的Servlet类实现了这三个接口中所有的方法,故也被称为页面实现类。

JspPage接口只申明了两个方法:jspInit()和jspDestroy()方法。所有的JSP页面都应该实现这两个方法。HttpJspPage接口中申明了一个方法:_jspService()。下面是这三个JSP方法的标志:

public void jspInit();

public void _jspService(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException;

public void jspDestroy();

这三个方法称为JSP页面的生命周期。JSP页面的jspInit()、_jspService()、jspDestroy()方法分别等价于Servlet的init()、Service()、destroy()方法。

[1]、jspInit()方法:容器调用该方法初始化Servlet实例。该方法是在任何其他方法调用之前调用的,并对每个Servlet实例只调用一次。通常在该方法中完成初始化或只需一次的设置工作。

[2]、_jspService()方法:对每次请求容器都调用一次该方法,并给他传递请求和相应对象。JSP页面中的所有HTML元素、JSP小脚本以及JSP表达式在转换阶段都成为该方法的一部分。

[3]、jspDestroy()方法:当容器决定停止该实例提供服务时,它将调用该方法,这是在Servlet实例上调用的最后一个方法,它主要用来清理jspInit()方法获得的资源。

一般不需要事先jspInit()和jspDestroy()方法,他们已经由基类实现了,但可以根据需要使用JSP的申明标签<%! ... %>覆盖这两个方法。然而,不能覆盖_就是jspService()方法,该方法由容器自动产生。

出处:http://blog.csdn.net/cl05300629/article/details/9368115 作者:伫望碧落