HttpSession的工作原理及相关常见问题

f663x 9年前

以下以session简称:

1、session的生命周期:session是在服务器第一次执行getSession()语句时才创建的(此方法:服务器先从浏览器带来的cookie中查找JSESSIONID,是否有相关可用的session,有就调用,如果没有,再从超链接的URL中查找 JSESSIONID,如果还没有,就会创建一个新的session。),如果session对象30分钟内没有被访问,服务器将自动销毁该session.
另外,
可以通过web.xml文件配置session的失效时间,单位为分钟
<seesion-config>      <session-timeout>10</session-timeout>  </seesion-config>
可以通过session.invalidate()方法来销毁session对象。


2、session的创建是基于cookie的,服务器在新创建session的时候,会自动为session设置一个ID信息,并以cookie的形式回写给浏览器,JSESSIONID=IDNumber,IDNumber是服务器自动生成的唯一的编码;当浏览器访问别的页面的时候,自动会带着该cookie信息,这样服务器会自动调用已生成的session,而不会重新创建session对象,或调用错误的session

3、服务器创建session对象时,生成的cookie是没有指定生存时间的,所以当浏览器意外关闭的时候,相应的cookie会随之销毁,这样用户再次访问相应的页面时,
上次保存的session对象也就找不到了,服务器会再次创建一个新的session对象。这种情况会造成:用户在浏览器意外关闭前,所有保存在session中的操作信息也随之丢失。    
    这样用户体验会相当不好,为了避免出现这种情况,我们需要将保存session对象ID信息的cookie设置一个生存时间,这样浏览器意外关闭的时候,cookie不会随之销毁,这样就保证了,用户在浏览器意外关闭后再次访问页面时,可以继续之前的相应操作。
方法:
1、先获取服务器新创建的session的ID
2、实例化一个与服务器回写给浏览器一样的cookie,以保存此ID信息
3、指定cookie可见的目录,要与服务器默认的相同,默认为相应的web应用

4、设置cookie的生存时间(最好是30分钟以内)
5、将此cookie回写给浏览器
实现代码:
HttpSession session = request.getSession();  String sessionid = session.getId();  Cookie cookie = new Cookie("JSESSIONID", sessionid);  cookie.setPath("path");   cookie.setMaxAge(30*60);  response.addCookie(cookie);
4、我们知道了session对象是基于cookie的,如果用户使用的浏览器把cookie禁用了,那么session将会失效。
解决此类问题的方法是:使用URL重写,即将所有涉及到的URL信息中加入session的ID属性JSESSIONID。

实现代码:
String newURL = response.encodeURL("odlURL")
对odlURL进行重写,返回的newURL中包含了session的ID值。

newURL的形式是:
如果odlURL中带有参数,则在?前加上
;JSESSIONID=IDNumber     
格式为:
——;JSESSIONID=IDNumber?——
如果oldURL中没有参数,则直接是oldURL;
JSESSIONID=IDNumber

encodeURL(String url)方法的一个实现细节:该方法执行的时候,服务器会判断浏览器是否带有JSESSIONID相关的cookie,如果有就不会再进行URL重写,如果没有就会进行URL重写。
    我们知道该方法是为了解决那些禁用或不支持cookie的浏览器出现的相关问题。那么对于支持cookie而且没有禁用cookie的情况下,我们仍使用URL重写的时候,会出现的情况:第一次访问的时候浏览器是没有带着JSESSIONID的相关cookie的,所以会进行URL重写,在此同时服务器把session的相关cookie信息回写给了浏览器,第二次再访问的时候浏览器带有
JSESSIONID的相关cookie,所以就不会再进行URL重写了。


注:对于那些禁用或不支持cookie的浏览器,通过URL重写后,当浏览器意外关闭面出现的session丢失的问题,是无法解决的!!!

 
对于健壮的会话跟踪,servlet 发出的所有 URL 都应该通过此方法运行。否则,session不能用于不支持 cookie 的浏览器。