-
存储位置:服务器端
-
底层原理:Session 的底层基于 Cookie 来实现的。
-
获取session:
- 第一次请求Session 会话对象是不存在的,这个时候服务器会自动的创建一个会话对象Session 。
- 每一个会话对象Session ,它都有一个ID(示意图中Session后面括号中的1,就表示ID),称之为 Session 的ID
-
响应Cookie(JSESSIONID)
- 服务器端在给浏览器响应数据的时候,它会将 Session 的 ID 通过 Cookie 响应给浏览器。
- cookie 的name是固定的 JSESSIONID 代表的服务器端会话对象 Session 的 ID。
- 本质是在响应头当中增加了一个 Set-Cookie 响应头。
- 浏览器会自动识别这个响应头,然后自动将Cookie存储在浏览器本地。
- 服务器端在给浏览器响应数据的时候,它会将 Session 的 ID 通过 Cookie 响应给浏览器。
-
查找Session
- 在后续的每一次请求当中,都会将 Cookie 的数据获取出来,并且携带到服务端。
- 之后服务器拿到JSESSIONID这个 Cookie 的值,也就是 Session 的ID,从众多的 Session 当中来找到当前请求对应的会话对象Session
-
优缺点
- 优点:Session是存储在服务端的,安全
- 缺点:
- 服务器集群环境下无法直接使用Session
- 移动端APP(Android、IOS)中无法使用Cookie
- 用户可以自己禁用Cookie
- Cookie不能跨域
- PS:Session 底层是基于Cookie实现的会话跟踪,如果Cookie不可用,则该方案,也就失效了。
-
服务器集群环境为何无法使用Session?
-
单点故障:某台服务器挂了,整个应用都没法访问
-
负载均衡服务器:将前端发起的请求均匀的分发给后面的服务器
-
【案例】
在现在的企业项目开发当中,最终部署的时候都是以集群的形式来进行部署,也就是同一个项目它会部署多份。比如这个项目我们现在就部署了 3 份。
此时假如我们通过 session 来进行会话跟踪。。用户打开浏览器要进行登录操作,此时会发起登录请求。登录请求到达负载均衡服务器,将这个请求转给了第一台 Tomcat 服务器
Tomcat 服务器接收到请求之后,获取到会话对象session。最终在给浏览器响应数据的时候,就会携带这么一个 cookie 的名字,就是 JSESSIONID
下一次再请求的时候,将 Cookie 携带到服务端。假如又执行了一次查询操作,这次请求到达负载均衡服务器之 后,负载均衡服务器将这次请求转给了第二台 Tomcat 服务器。而第二台服务器当中有没有这个ID的会话对象 Session, 是没有的。
同一个浏览器发起了 2 次请求,结果获取到的不是同一个会话对象, 这就是Session这种会话跟踪方案它的缺点,在服务器集群环境下无法直接使用Session。
-
代码测试
-
设置Session数据
通过HttpSession对象往session设置数据
HttpSession对象.setAttribute("key",value);
代码演示
@GetMapping("/s1") public Result session1(HttpSession session){ log.info("HttpSession-s1: {}", session.hashCode()); //往session中存储数据 session.setAttribute("loginUser", "tom"); return Result.success(); }
请求完成之后,在响应头中,就会看到有一个Set-Cookie的响应头,里面响应回来了一个Cookie,就 是JSESSIONID,这个就是服务端会话对象 Session 的ID。
-
获取Session数据
获取Session对象
HttpServletRequest对象.getSession(); //返回的是httpSession
通过Session对象的key属性获取value属性的值
Session对象.getAttribute("name"); //返回Object
代码演示
@GetMapping("/s2") public Result session2(HttpServletRequest request){ HttpSession session = request.getSession(); log.info("HttpSession-s2: {}", session.hashCode()); //从session中获取数据 Object loginUser = session.getAttribute("loginUser"); log.info("loginUser: {}", loginUser); return Result.success(loginUser); }
在后续的每次请求时,都会将Cookie的值,携带到服务端,那服务端呢,接收到Cookie之 后,会自动的根据JSESSIONID的值,找到对应的会话对象Session。那这样,我们就可以通过 Session会话对象,在同一个会话的多次请求之间来进行数据共享了
参考文献:黑马javaWeb视频