Session实现原理
- 结论:
Session
实现依赖Cookie
的 - 图解
- SessionDemo1代码
@WebServlet("/session1")
public class SessionDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 重点就这两行
HttpSession s = request.getSession();
s.setAttribute("msg", "Session");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
- SessionDemo2代码
@WebServlet("/session2")
public class SessionDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 重点就这三行
HttpSession s = request.getSession();
Object msg = s.getAttribute("msg");
System.out.println(msg);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
-
当浏览器第一次访问
/session1
时发送的没有cookie
的请求头,然后服务器穿件一个Session
后在进行后续赋值Key/value
操作,最后会自动返回一个Cookie
信息
-
当我们再次访问
/session2
时,会将所有的Cookie
发送给服务器,服务器
读取到Cookie名为JSESSIONID
的值,然后再内存中创建的Session对象
做对比,然后再进行取值后续操作。
-
结论:
Session
实现依赖Cookie
的
客户端关闭后,服务器不关闭,一定时间内获取的Session为同一个
- 因为
Session
默认是设置Cookie
key为JSESSIONID
,默认是关闭浏览器即清除Cookie
那么我们可以通过设置JSESSIONID
的Cookie
存活时间达到目的。 - 代码
HttpSession s = request.getSession();
System.out.println(s);
Cookie cookie = new Cookie("JSESSIONID", s.getId());
cookie.setMaxAge(60 * 60); // 一个小时自动删除
response.addCookie(cookie);
- 多次浏览器关闭后访问
结果
org.apache.catalina.session.StandardSessionFacade@4c1c316c
org.apache.catalina.session.StandardSessionFacade@4c1c316c
org.apache.catalina.session.StandardSessionFacade@4c1c316c
浏览器不关闭,服务器关闭,两次访问返回的SESSION值是一样的吗?
不一样
,服务器关闭后,Session
对象会被销毁,再次开启服务器访问时,内存中没有Session
对象,无法跟请求头
传过来的值匹配到。- 在
tomcat
中,它会session钝化
(服务器正常关闭前,将Session
对象序列化在硬盘上,序列化)再Session活化
(服务器启动后,将Session
文件转换为内存中的Session对象
,反序列化) - 演示:
// 主要代码块SessionDemo1
HttpSession s = request.getSession();
s.setAttribute("msg", "Session");
// 主要代码块SessionDemo2
HttpSession s = request.getSession();
Object msg = s.getAttribute("msg");
System.out.println(msg);
第一次访问/session1
后再访问/session2
服务器打印的结果
正常关闭tomcat
进行第二次直接访问/session2
,开启服务器反序列化
并删除文件
,再访问,此时地址可能不一样
,但是里面存储的内容一定是一样的。
- IDE编译器无法
反序列化的原因
是:它序列化确实也是在work
文件夹下,但是重新启动服务器则会先删除wiork
文件夹再进行反序列化
Session失效时间
- 服务器关闭
Session对象
调用invalidate()
方法Session默认失效时间
在web.xml
中修改,可以在tomcat服务器中改
,也可以每个项目的web.xml
中配
<Session-config>
<Session-timeout>多少分钟</Session-timeout>
</Session-config>