首页 新闻 会员 周边 捐助

Cookie和Session

0
[已解决问题] 解决于 2021-10-11 21:17

测试如下

@RequestMapping("/test")
    public void test(HttpServletRequest request) {
        Logger logger = LoggerFactory.getLogger(Test.class);
        Cookie[] cookies = request.getCookies();
        for(Cookie cookie : cookies){
            if("user".equals(cookie.getName()))
                System.out.println("user");
            if("JSESSIONID".equals(cookie.getName())) {
                System.out.println("JSESSIONID");
                System.out.println("ID-Cookie :" + cookie.getValue());
                HttpSession session = request.getSession();
                logger.info("Session", session);
                logger.info("ID : " + session.getId());
            }
        }
        System.out.println(cookies.length);
    }

启动SpringBoot,第一次访问时,session.id和jssionid不相同,第二次访问路径,session.id和jsessionid变得相同。关闭项目重新启动SpringBoot,第一次访问,session.id和jsessionid任然不相同,但是session.id和项目上次关闭时最后一次的jsessionid相同。
猜想如下,项目运行时,服务端会将上次最后访问的jsessionid作为session.id,而浏览器第一次访问服务器时,会生成jsessionid,但是不会发送Cookie,只有第二次访问服务器时,才会发送Cookie,这时服务器的session.id才会和jsessionid同步(上次的session.id被覆盖)。
这样理解Cookie和Session有不对的吗?

up-bear的主页 up-bear | 初学一级 | 园豆:134
提问于:2021-10-07 21:52
< >
分享
最佳答案
0

第0步 :清理下浏览器cookie:
第一次访问 :浏览器cookie中没有 sessionid ,所以服务端会生成sessonid 并通过cookie下发 ; [sessionid='' jsessionid='aaa']
第二次访问: 浏览器携带cookie 请求服务端 , 服务端去自己内存中找这个sessionid(aaa) ,存在不再下发新的id了 ; [sessionid='aaa' jsessionid='aaa']
服务端重启后:服务端内存中的session id被清空
第三次访问: 浏览器会携带第一次服务端下发的 cookie 请求服务端 , 服务端去自己内存中找这个id ,找不到 ,会下发新的session id ,浏览器接受到会更新再 cookie中保存的sessionid ; [sessionid='aaa' jsessionid='bbb']
第四次访问: 这次浏览器携带的是第三次生成的sesionid (bbb)访问服务端 ; [ sessionid='bbb' jsessionid='bbb']

总结: 服务端的sessionid 是获取的客户端上传过来的cookie中的sessionid ,服务端的jsessionid 是内存中维护的即将下发的session id ;

session 是会话的意思 , 是浏览器和服务端建立会话 , 因为http协议是无状态的,于是有了cookie的诞生 ,让服务端知道本次请求 是上次那个小王发出的 。 第一次访问,服务端不知道是谁访问的,于是给了它一个id ,让它保存好,以后每次访问我都携带上,放到cookie请求头里面 , 于是会话就建立了 ,服务单知道 本次请求和上次是同一个 id发出的 。

奖励园豆:5
地菜 | 菜鸟二级 |园豆:208 | 2021-10-09 10:34

嗯确实,我还纳闷为什么服务器重启后,sessionid和jsessionid不同,原来如此。感谢解答哦。

up-bear | 园豆:134 (初学一级) | 2021-10-09 21:54
其他回答(1)
0

而浏览器第一次访问服务器时,会生成jsessionid,但是不会发送Cookie

只要当前域名下有 cookie名为 jsessionid,就会 传到服务器。
所以,你上面的 这个说法 是不太对的。

Chrome浏览器,控制台,Application》Storage》Cookies,,可以去看看。

重启湖,服务端的session id为什么变化(过滤器?)了,可以去看源码(孤还没定位到具体位置)

快乐的欧阳天美1114 | 园豆:4010 (老鸟四级) | 2021-10-07 23:09

尝试debug了下,发现程序执行到位于connector/Request类下的ServerCookies serverCookies = coyoteRequest.getCookies();这一句时,serverCookies已经有了jsessionid的cookie,coyoteRequest的定义是protected org.apache.coyote.Request coyoteRequest;
继续看serverCookies = coyoteRequest.getCookies();发现自己看不懂了,coyoteRequest.getCookies()方法返回一个ServerCookies类型的serverCookies,ServerCookies serverCookies = new ServerCookies(INITIAL_COOKIE_SIZE);INITIAL_COOKIE_SIZE值为4,然后调用ServerCookies的构造方法,有调用ServerCookie的构造方法,然后发现ServerCookie没有有参构造方法。。。
晕,什么鬼啊

支持(0) 反对(0) up-bear | 园豆:134 (初学一级) | 2021-10-08 19:27

@up-bear:
org.apache.catalina.connector.Request类位于 tomcat-embed-core-*.jar 包中,session 的管理,默认都是 tomcat服务器 来管理的吧。
debug好像会 执行到 某个 动态代理类,就看不到源码了。
后来我没有继续追了...

上面是 由 Tomcat来管理session。

前面的一篇博文:session相关
https://www.cnblogs.com/luo630/p/15321807.html

支持(0) 反对(0) 快乐的欧阳天美1114 | 园豆:4010 (老鸟四级) | 2021-10-08 19:45

又用火狐试了下,发现第一次访问时服务端的得到的cookie为空,也就是说浏览器第一次访问服务器时并不会生成jsessionid。
第二次访问时,浏览器确实生成了jsessionid,在debug时服务端好像是经过了一些Fiter类。有个细节,在我第一次用火狐访问时,浏览器是没有jsessionid的,但是访问结束后,就sessionid就出现了,似乎是服务端发送了“命令”让浏览器生成jsessionid,所以浏览器在第二次访问时会发送cookie。

支持(0) 反对(0) up-bear | 园豆:134 (初学一级) | 2021-10-08 20:35

@up-bear:
cookie 是 浏览器存储的,和服务器无关,,服务器只是从 请求中获取cookie,
cookie 可以有很多个,这里的jsession是和 session相关的cookie(spring boot可以更改这个名字——配置),

第一次请求s.b.,s.b.建立session,然后,把这个 session 的值 作为cookie 返回给 浏览器(客户端),
之后访问时,只要cookie没有过期,就会把 这个 cookie——jsession——带到请求头中,传给服务器,
然后就是 前面你调试到的 getCookies了。

支持(0) 反对(0) 快乐的欧阳天美1114 | 园豆:4010 (老鸟四级) | 2021-10-08 20:39

@快乐的凡人721: 清晰了,谢谢老哥。

支持(0) 反对(0) up-bear | 园豆:134 (初学一级) | 2021-10-08 21:54
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册