博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
详解Session的生命周期
阅读量:4039 次
发布时间:2019-05-24

本文共 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/

你可能感兴趣的文章
Ubuntu Server 16.04修改IP、DNS、hosts
查看>>
几个可以替代百度的搜索引擎
查看>>
BT.656标准简介
查看>>
BT.601与BT.656
查看>>
标准BT.656并行数据结构
查看>>
A Brief Introduction to Digital Video
查看>>
数字视频接口
查看>>
my.cnf 自动生成脚本
查看>>
如何通过instant client 来连接数据库以及使用exp/imp?
查看>>
flask +python+vue 监控软件(一)
查看>>
flask +python+vue 监控软件(二)
查看>>
go AES加密解密
查看>>
python AES加密解密,key的长度不受限制
查看>>
oracle 查询sequnce# 在哪个归档备份集下面
查看>>
使用kettle 增量同步mysql到oracle以及oracle到mysql的测试
查看>>
MySQL8.0与MySQL5.7 OLTP 性能测试对比
查看>>
mongodb 分片集群安装搭建测试
查看>>
mycat 连接mongodb
查看>>
rsync 拉取备份文件(支持断点续传)
查看>>
Golang 数据可视化利器 go-echarts ,实际使用
查看>>