6.1.3 JSP声明
虽然使用<%...%>可以将任何Java代码直接插入到_jspService方法中,但是如果想在_jspService方法外插入Java代码,<%...%>却无能为力。要想达到这个目的,就必须要使用JSP声明。JSP声明中的Java代码被封装在<%!...%>中。所有在<%!...%>中的Java代码都会被作为Servlet类的全局部分插入到_jspService方法外。如下面的JSP代码所示:
<!-- declare.jsp -->
<!-- JSP声明 -->
<%!
static
{
System.out.println("正在装载Servlet!");
}
private int globalValue = 0;
public void jspInit()
{
System.out.println("正在初始化JSP!");
}
public void jspDestroy()
{
System.out.println("正在销毁JSP!");
}
%>
<!-- 在_jspService方法中插入Java代码 -->
<%
int localValue = 0;
%>
globalValue:<%= ++globalValue %><br>
localValue:<%= ++localValue %>
在上面的JSP代码中使用JSP声明做了如下三件事:
l 在Servlet类中插入了一个静态块(static {...})。
2 定义了一个全局的int类型变量globalValue,并将该变量初始化为0。
3 覆盖了由JSP生成的Servlet类中的jspInit和jspDestroy方法。这两个方法分别在该Servlet对象初始化和销毁时被调用。
declare.jsp页面将被JSP引擎翻译成如下的Servlet类源代码:
... ...
public final class declare_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent
{
static
{
System.out.println("正在装载Servlet!");
}
private int globalValue = 0;
public void jspInit()
{
System.out.println("正在初始化JSP!");
}
public void jspDestroy()
{
System.out.println("正在销毁JSP!");
}
... ...
public void _jspService(HttpServletRequest request, HttpServletResponse
response) throws java.io.IOException, ServletException
{
... ...
int localValue = 0;
out.write("\r\n");
out.write("globalValue:");
out.print(++globalValue);
out.write("<br>\r\n");
out.write("localValue:");
out.print(++localValue);
... ...
}
}
从上面的Servlet源代码可以看出,所有<%!...%>中的内容都被作为declare_jsp类的全局部分插入到declare_jsp类中。
在浏览器地址栏中输入如下的URL:
http://localhost:8080/demo/chapter6/declare.jsp
当首次访问上面的URL时,Tomcat控制台会输出如下的信息:
正在装载Servlet!
正在初始化JSP!
浏览器将显示如下的信息:
globalValue:1
localValue:1
在多次访问上面的URL后,由于globalValue是declare_jsp的全局变量,因此,在declare_jsp对象未被销毁之前,globalValue变量的值在每刷新一次页面时就会增1,而localValue是在_jspService方法定义的局部变量,因此,localValue变量始终是1。
修改declare.jsp页面中的内容(只要加几个空格或回车即可,目的就是该变declare.jsp页面的修改时间),然后再次访问上面的URL,Tomcat控制台会输出如下的信息:
正在销毁JSP!
正在装载Servlet!
正在初始化JSP!
从上面的输出信息可以看出,当修改JSP页面后,再次访问该JSP页面,JSP引擎会重新将该JSP页面翻译成Servlet,而Servlet引擎会先销毁以前由该JSP页面生成的Servlet的对象实例,然后再重新装载该Servlet。