概述:
客户端会话技术cookie是保存在客户端浏览器的,那么与之相对的服务器端会话技术session是保存在服务器端的。
会话技术旨在数据的共享,下面一段session的代码演示:
@WebServlet("/servletSession01") public class ServletSession01 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session对象 HttpSession session = request.getSession(); session.setAttribute("name","zhangsan"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
资源类2:
@WebServlet("/servletSession02") public class ServletSession02 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession();//获取session String name = (String) session.getAttribute("name"); System.out.println(name); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
图解session对象创建的传递过程:
服务器如何确保在一次会话范围内多次获取的session对象是同一个?
session在客户端和浏览器之间的传递是依赖于cookie的
-
在调用request方法的getsession();方法时:
- 如果是本次会话第一次调用此方法
- 那么服务器就会在内存中创建一个新的session对象
- 并且会给这个内存的session对象分配id值(如上图的742938a4289)
- 在服务器响应浏览器是会在响应头中有set-cookie:JSESSIONID=742938a4289 (JSESSIONID是一个特殊的响应头标记它代表的就是session依赖)
- 浏览器再次访问会在请求头中含有cookie:JSESSIONID=742938a4289
- 当本次会话再次请求获得session对象是,会根据JSESSIONID寻找session对象内存地址
- 如果不是本次会话中第一次
- 重复第一次会话的最后两个步骤
- 如果是本次会话第一次调用此方法
通过浏览器开发者模式验证上面的说法:
第一次请求资源类1的响应头:
第一次请求资源类2请求头:
可以看出两幅图的JSESSIONID是相同的
判断以下三种情况获得的session对象是不是同一个对象:
- 客户端关闭服务器不关闭:
- 不是同一个对象,因为session对象在客户端和浏览器之间的会话是依赖于cookie对象的,如果关闭浏览器虽然session对象并不会被销毁,但是它所依赖的cookie对象在浏览器端会被销毁(默认情况下),多以再次访问服务器并不会含有上一次创建session对象的JSESSIONID的请求头,所以服务器会创建一个新的session对象
- 希望浏览器关闭后还可以访问到同一个session的解决办法:
- 设置一个cookie对象键为:JSESSIONID,值是session的内存id(通过session.getId();方法获得),然后设置它的存活时间,就是可以找到相同session的时间间隔
代码如下:
@WebServlet("/servletSession02") public class ServletSession02 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession();//获取session String name = (String) session.getAttribute("name"); Cookie cookie=new Cookie("JSESSIONID",session.getId());//手动设置依赖cookie cookie.setMaxAge(60*5);//设置依赖cookie的存活时间为5分钟 response.addCookie(cookie); System.out.println(name); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
2.客户端不关闭服务器关闭:
在idea中访问的并不是同一个,但是在实际开发中这样访问的其实会是同一个session对象,原因是:
- 如果是正常关闭服务器,那么在服务器关闭之前会将内存中的session对象序列化(钝化)到硬盘中
- 然后再次启动服务器的时候就会将上次关闭时序列化的session对象重新活化到内存中
Session对象的失效时间:
- 服务器关闭
- session对象的自杀方法:invalidate();
- session的默认失效时间是30分钟(在Tomcat的主配置文件web.xml中配置标签
<session-config>
)
<session-timeout>30</session-timeout>
</session-config>
session的特点:
- session用于存储一次会话的多次请求的多次请求的数据,存储在服务器。
- session可以存储任意类型(指的是值,键只能String,cookie键值只能是String),任意大小的数据