三、Tomcat中的JSP和Session
从本质上讲,JSP在运行时已经被编译成相应的Servlet了,因此,在JSP和Servlet中Session的使用方法应该差不多。但还是有一些细小的差别。
如果我们使用过JSP就会发现,在JSP中很多对象是不需要创建的,如out、session等。它们可以直接使用。如下面的JSP代码所示:
<!-- MyJSP.jsp -->
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>Insert title here</title>
</head>
<body>
<%
out.println(session.getId());
%>
</body>
</html>
由于JSP在第一次运行时是被编译成Servlet的,我们自然就会想到有可能是在编译JSP时自动创建了session和out对象。下面我们就来验证这一点。首先需要查看一下JSP被编译成Servlet后的源代码。这非常简单,如果我们使用的是Tomcat,只需要在Tomcat的安装目录中的work中找相应的源程序即可。如一个名为MyJSP.jsp的文件首先被编译成MyJSP_jsp.java(这就是由JSP生成的Servlet源程序文件),然后再由java将MyJSP_jsp.java编译成MyJSP_jsp.class,最后Tomcat运行的就是MyJSP_jsp.class。如上面的JSP程序被编译成Servlet的部分源代码如下:
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class MyJSP_jsp extends org.apache.jasper.runtime.HttpJspBase
{
... ...
... ...
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=GB18030");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
out.write("<html>\r\n");
out.write("\t<head>\r\n");
out.write("\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=GB18030\">\r\n");
out.write("\t\t<title>Insert title here</title>\r\n");
out.write("\t</head>\r\n");
out.write("\t<body>\r\n");
out.write("\t\t");
out.println(session.getId());
out.write("\r\n");
out.write("\r\n");
out.write("\t</body>\r\n");
out.write("</html>");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
我们可以看到上面的代码中的_jspService方法类似于HttpServlet中的service方法,在方法的开始部分首先建立了session、application、out等对象实例。然后将MyJSP.jsp中的HTML通过out输出到客户端。我们要注意上面的黑体字的语句:out.println(session.getId());,JSP编译器自动将JSP中的<% ... %>中包含的Java代码原封不动地插入到_jspService中。由于是在创建对象实例后插入,因此,就可以直接使用session、out等对象了。
如果我们想做进一步的实验,可以直接使用javac来编译MyJSP_jsp.java,为了方便其间,首先建立一个c.cmd文件,它的内容如下:
如果我们想做进一步的实验,可以直接使用javac来编译MyJSP_jsp.java,为了方便其间,首先建立一个c.cmd文件,它的内容如下:
javac -classpath
D:\tools\apache-tomcat-6.0.13\lib\servlet-api.jar;D:\tools\apache-tomcat-6.0.13\lib\jsp-api.jar;D:\tools\apache-tomcat-6.0.13\lib\annotations-api.jar;D:\tools\apache-tomcat-6.0.13\lib\catalina.jar;D:\tools\apache-tomcat-6.0.13\lib\jasper.jar;D:\tools\apache-tomcat-6.0.13\lib\el-api.jar %1
其中D:\tools\apache-tomcat-6.0.13是tomcat的安装目录,读者可以将其设为自己的机器上的tomcat安装目录
在编译时可直接使用c MyJSP_jsp.java进行编译,这时tomcat就直接运行我们编译生成的MyJSP_jsp.class了。
从上面的代码我们还可以了解一点,在JSP无论使用还是不使用session,都会使用getSession方法创建一个Session对象,而Servlet必须显式地调用才会建立Session对象。
注:通过直接编译java文件运行jsp,需要清除一下tomcat的缓存,一般需要重启一下tomcat。
其中D:\tools\apache-tomcat-6.0.13是tomcat的安装目录,读者可以将其设为自己的机器上的tomcat安装目录
在编译时可直接使用c MyJSP_jsp.java进行编译,这时tomcat就直接运行我们编译生成的MyJSP_jsp.class了。
从上面的代码我们还可以了解一点,在JSP无论使用还是不使用session,都会使用getSession方法创建一个Session对象,而Servlet必须显式地调用才会建立Session对象。
注:通过直接编译java文件运行jsp,需要清除一下tomcat的缓存,一般需要重启一下tomcat。