- 那么可以在Filter中把这个Request给换掉,可以采用动态代理的方式仅仅改变getSession的方法或者使用装饰者模式,把获取session的方法改成从某个存储中获取,这样多个系统之间就可以实现session共享,但是也很清晰的看到有很大的局限性,毕竟这是依托借助浏览器携带session的特性来实现的。感觉这个思路是没什么问题,但是这个Session的持久化这个问题好像还真不知道怎么搞,看样子,是要反序列化回来么??感觉其实还是因为没有看到tomcat创建session的源码,以及Session接口的规范要求,所以这是个盲点。后面看看spring-session是怎么搞的,然后再探究吧
- 在前后端分离项目里面,我们借助网关,浏览器通过网关来调用不同的子系统,那么都会携带cookie到网关,而在不同的子系统就可以拿到cookie,从而实现共享。
- session的默认path就是项目的contextPath
首先搭建一个简单的demo,看下session的一些特点
其实就一个controller,
@RestController
public class MyController {
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
@RequestMapping("set")
public String set() {
Cookie cookie = new Cookie("name", "zzhua");
response.addCookie(cookie);
return "ok";
}
@RequestMapping("get")
public String get() {
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + ":" + cookie.getValue());
if (cookie.getName().equals("name")) {
return cookie.getValue();
}
}
return "null";
}
@RequestMapping("setSession")
public String setSession() {
HttpSession session = request.getSession();
session.setAttribute("attr", "123");
return "ok";
}
@RequestMapping("getSession")
public Object getSession() {
HttpSession session = request.getSession(false);
if (session!=null) {
Object attrValue = session.getAttribute("attr");
return attrValue;
}
return "no session";
}
@RequestMapping("invalidSession")
public String invalidSession() {
HttpSession session = request.getSession();
session.invalidate();
return "session invalid";
}
}
第一个结论:如果浏览器没有携带JSESSIONID的cookie,或者浏览器携带了JSESSIONID的cookie,但是服务端的session已经失效了,这时服务器会创建一个session,并且设置Set-Cookie的响应头返回给浏览器,浏览器就会保存这个JSESSIONID的cookie。如果没有失效,那就用原来的。
第二个结论:浏览器保存JSESSIONID的cookie对于同一个ip(我这里只测试了ip,不知道跟domain有没有关系),不同端口的项目,访问其中一个项目,浏览器被设置cookie后,再访问第二个项目,根据前面对cookie的测试,它会依旧携带上一个项目的cookie,也就是JSESSIONID的cookie到第二个项目去拿session,发现拿不到,于是第二个项目又写回Set-Cookie的请求头给浏览器,浏览器这个时候,是直接把原来的Cookie给覆盖掉了,并且去访问第一个项目的时候,把这个被覆盖的cookie又携带过去了
第三个结论:服务器写响应头Set-Cookie到浏览器,浏览器会保存起来。下次再去访问服务器时会自动携带对应path路径下的cookie,放在请求头里(所以后台能够通过请求头拿到)。其实从这一点,也可以看出来客户端与服务器请求与响应过程的实质,其实就是通过请求头、请求体、请求url、响应头、响应体,进行交互的。
cookie的有效时间可以通过Cookie#setMaxAge来指定,设置负值表示浏览器一退出就不会保存cookie了,设置0表示,立即删除此cookie,设置正值表示该cookie的最大存活秒数