日期:2014-05-16  浏览次数:20316 次

jsp环境下session的创建

1)-不恰当的request.getSession()

在HttpServlet中,HttpSession对象通常在request.getSession(true)方法调用时才创建。 HttpSession的使用是有代价的,需要占用服务器资源,本着能不浪费就不浪费的原则,我希望系统中的session都在掌握之中,在需要创建时由 我们的代码明确创建。但是最近在开发中发现,新的session对象经常在意料之外出现,究竟是谁在创建session呢?

最常见的地方是错误的使用request.getSession()函数,通常在action中检查是否有某个变量/标记存放在session中。 这个场景中可能出现没有session存在的情况,正常的判断应该是这样:


Java代码

?? 1. private boolean ifFlagExistInSession(HttpServletRequest request) ...{
?? 2.???? HttpSession session = request.getSession(false);
?? 3.???? if (session != null) ...{
?? 4.???????? if (session.getAttribute("flagName") != null) ...{
?? 5.???????????? return true;
?? 6.???????? }
?? 7.???? }
?? 8.???? return false;
?? 9. }

而下面的写法,则可能会生成一个新的不在我们意图之外的session:

Java代码

?? 1. private boolean ifFlagExistInSession(HttpServletRequest request) ...{
?? 2.???? HttpSession session = request.getSession();?? // a new session created if no session exists
?? 3.???? if (session.getAttribute("flagName") != null) ...{
?? 4.???????? return true;
?? 5.???? }
?? 6.???? return false;
?? 7. }

注意request.getSession() 等同于 request.getSession(true),除非我们确认session一定存在或者sesson不存在时明确有创建session的需要,否则 请尽量使用request.getSession(false)。


(2)-悄悄干活的jsp
jsp文件是session创建的一个源头,这里指的不是在jsp文件中用代码或者标签来操作session,这些都是在控制中的。容易忽视或者说根本就 不会意识到的(比如我,就是写jsp三年后才发现的)是,jsp有自动创建session的机制,在jsp页面中,如果没有明确的给出 <% @page session="false"%>,jsp页面会非常乖巧(如果刚好需要)或者说是偷偷摸摸(如果不需要)的自动在生成的java文件中增加一 句: javax.servlet.http.HttpSession session = request.getSession(true)。

为了验证这个说法,我们做以下测试,先来一个最简单的jsp文件,名字也简单a.jsp,放到resin下。a.jsp的内容如下,注意里面有一 个<%=1%>,后面会详细解释为什么需要这句话:


Java代码
<%@ page session="true"%>??
<html>??
<head>??
<title>test</title>??
</head>??
<body>??
<%=1%>??
</body>??
</html>??

用页面访问一下,然后到resin下webapp目录的WEB-INF/work/_jsp目录下找到_a__jsp.java,打开可以看到
public class _a__jsp extends com.caucho.jsp.JavaPage
有关jsp页面是如何转换为java文件再被编译成class的介绍,请google。看我们关心的public void _jspService()方法:


Java代码
public void _jspService(javax.servlet.http.HttpServletRequest request,??
????????????? javax.servlet.http.HttpServletResponse response)??
??? throws java.io.IOException, javax.servlet.ServletException??
{??
??? javax.servlet.http.HttpSession session = request.getSession(true);??
??? com.caucho.server.webapp.Application _jsp_application = _caucho_getApplication();??
可以看到第一行,明确的调用了request.getSession(true),session就是再这里被自动创建的,这里也就是JSP中隐含的 session对象的来历。
使用抓包软件,可以看到请求这个jsp页面的http response里面有以下内容:
Set-Cookie: JSESSIONID=abc0zn72YuHtacvaaORBr; path=/
这个是刚才创建的session的jsessionid,被保存到cookie中。

然后继续测试,设置为
<%@ page session="false"%>

打开java文件:

Java代码
public void _jspService(javax.servlet.http.HttpServletRequest request,??
????????????? javax.servlet.http.HttpServletResponse response)??
??? throws java.io.IOException, javax.servlet.ServletException??
{??
??? com.caucho.server.webapp.Application _jsp_application = _caucho_getApplication();??

没有javax.servlet.http.HttpSession session = request.getSession(true);
这行代码了,同时http response 中没有Set-Cookie: JSESSIONID=***的语句了。
ok,这下清晰了。

再来解释一下为什么要在刚才的jsp文件里面增加<%=1%>这行,我们先做测试,将<%=1%>删除,同样测试& lt;%@ page session="true/false"%>两种情况。可以看到

Java代码
public void _jspService(javax.servlet.http.HttpServletRequest request,??
????????????? javax.servlet.http.HttpServletResponse response)??
??? throws java.io.IOException, javax.servlet.ServletException??
{??
??? javax.servlet.http.HttpSession session = request.getSession(true);??


则不管是否有<%@ page se