本文共 4353 字,大约阅读时间需要 14 分钟。
在进行WEB Application开发的时候,很多程序员在理解Session的时候,常常会被误导,错误的认为:一个浏览器只有一个Session, 浏览器关闭Session就消失了。其实这是不正确的。(很多程序员是去baidu,或者google一下,只解决了当下的问题,但是对于更深次的问题没有仔细思考!)
要了解Session首先要知道一个概念:Session的销毁只有两种情况:
第一:成功地调用了 session.invalidate()方法。
第二:前后两次请求超出了session指定的生命周期时间。其中Session的生命周期时间可以在web.xml配置,默认30分钟。
在web.xml文件中可以做如下配置:
<session-config> <session-timeout>5</session-timeout> </session-config>上述配置表示:session的有效时间为 5分钟。注意:单位是分钟。
如何来证明关闭浏览器的时候Session没有销毁呢?我们可以创建一个SessionListener 此监听器专门用来监听Session的生命周期的。
此处插入样例代码:
package com.mrbean.commons.utils;
import java.util.Date; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import org.hibernate.HibernateException; import org.hibernate.Session;
public class SessionListener implements HttpSessionListener{ //监听Session的创建 public void sessionCreated(HttpSessionEvent event) { System.out.println("session已创建,时间:"+new Date().toLocaleString());
System.out.println(event.getSession().getId()); //此处省略一些代码 } //监听Session的销毁 public void sessionDestroyed(HttpSessionEvent event) { System.out.println("session已销毁,时间:"+new Date().toLocaleString());
System.out.println(event.getSession().getId()); //此处省略一些代码 } /**更新*/ public void updateObject(Object entity) { Session session=HibernateUtils.getSession(); try { session.getTransaction().begin(); session.update(entity); session.getTransaction().commit(); } catch (HibernateException e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { HibernateUtils.closeConnection(session); } } }
web.xml中的配置Session监听的代码:
<listener> <listener-class>com.mrbean.commons.utilsSessionListener</listener-class> </listener>
关于Session失效时间的配置:
<session-config> <session-timeout>5</session-timeout> </session-config>
配置完毕后,可以做个测试。 当浏览器关闭后此监听器的 sessionDestroyed方法并没有执行,而是在5分钟左右才会触发sessionDestroyed,当然 再打开浏览器的时候
ssessionCreated 会自动调用。 关闭5分钟后sessionDestroyed 又会自动调用,通过getID方法大家可以判断是否为同一个Session。
控制台监控,获得输出信息:
session已创建,时间:2014-11-30 17:04:04 D5AB6933ABFFFC6F65736C188CF562CE
session已销毁,时间:2014-11-30 17:10:35 D5AB6933ABFFFC6F65736C188CF562CE
(个人笔记本上做的测试,时间上存在一些误差),存在一些时间误差。
这个时候通过浏览器的关闭按钮,强制关闭浏览器。
然后打开一个新的浏览器,直接输入需要访问的页面地址,我们发现不用登陆系统,可以直接打开你想访问的页面。(而第一次访问该页面时,需要首先登陆系统,才可以访问。)
注意:如果没有任何配置的情况下,关闭浏览器30分钟后Session才会消失的。
我们可以利用这个Session监听做什么呢? 最典型的就是利用 SessionListener 的sessionDestroyed方法来记录用户非正常退出的时间。用户在访问某个网站的时候(目前很多网站都应用了这种方式) 显示了用户的最后登录时间。 此时间如何获取?
在这里分两种情况:
Case 1:如果用户按"退出" 按钮那就好说了,跳转到action中,记录下用户退出的时间。 存储到持久层中。
Case2: 如果用户非正常退出, 在没有配置Session的情况下,默认会在30分钟后调用sessionDestroyed。那么我们同样可以在此获取用户退出的时间,在sessionDestroyed 调用业务逻辑完成我们想要实现的功能。
有关Session第2个典型的应用就是Session中存储了用户的登录信息, 那么就可以访问用户权限的一些页面。
有关这个应用要注意一个问题:存储到session中的 User对象一定要实现Serializable接口。 Serializable的作用可以参考相关资料。正常情况下当我们做测试的时候关闭Tomcat 大家会在Tomcat安装目录\work\Catalina\localhost\项目名 文件夹下面看到有一个SESSIONS.ser 的文件。此文件就是Session在Tomcat停止的时候 持久化到硬盘中的文件。 所有当前访问的用户Session都存储到此文件中。 Tomcat启动成功后.SESSIONS.ser 又会反序列化到内存中,所以启动成功后此文件就消失了。 所以正常情况下从启Tomcat用户是不需要登录的。 注意有个前提就是存储到Session里面的user对象所对应的User类必须要序列化才可以。
另外补充:
Session存储在服务器端,一般为了防止在服务器的内存中(为了高速存取),Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。
Session什么时候失效? 1. 服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为20分钟。 2. 调用Session的invalidate方法。 Session对浏览器的要求: 虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。 该Cookie为服务器自动生成的, 它的maxAge属性一般为-1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。 注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择"在新窗口中打开"时,子窗口便可以访问父窗口的Session。 如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了另一种解决方案:URL地址重写。 URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。HttpServletResponse类提供了encodeURL(String url)实现URL地址重写,该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。 注意:TOMCAT判断客户端浏览器是否支持Cookie的依据是请求中是否含有Cookie。尽管客户端可能会支持Cookie,但是由于第一次请求时不会携带任何Cookie(因为并无任何Cookie可以携带),URL地址重写后的地址中仍然会带有jsessionid。当第二次访问时服务器已经在浏览器中写入Cookie了,因此URL地址重写后的地址中就不会带有jsessionid了。转载地址:http://lovdi.baihongyu.com/