SpringSession DefaultCookieSerializer.setJvmRoute works, but HttpServletRequest does not have the jvmRoute required

耗尽温柔 提交于 2020-01-04 07:14:12

问题


I have implemented Spring Session with Redis in my legacy Spring MVC application. I also used the DefaultCookieSerializer to set the jvmRoute, because I need some server affinity for Talend jobs to be able to run.

When I run the front end and inspect the page in Chrome, I see the jvmRoute appended to the session. If I edit this from "node1" to "node2", the session is preserved. If I redeploy the server and make requests during that deployment, I get redirected to another node in the cluster, which means that Spring Sessions is working perfect.

However, I cannot get server affinity because when I debug a HttpServletRequest as it comes into my Spring app, the HttpServletRequest.getSession().getId() doesn't have the jvmRoute in it (although the hex number matches what I see in Chrome), and this is what I pass to the Talend job.

If I revert back to Tomcat session and set the jvmRoute in the Engine component of server.xml, I see the jvmRoute appended to the session id in both Chrome and when debugging the code.

What exactly does the DefaultCookieSerializer do? I thought it edits the cookie as it is being created, and that is how the cookie is to be stored in Redis. So any use of this cookie subsequent to being created should have the jmvRoute attached if you set it up that way.


回答1:


What exactly does the DefaultCookieSerializer do? I thought it edits the cookie as it is being created, and that is how the cookie is to be stored in Redis. So any use of this cookie subsequent to being created should have the jmvRoute attached if you set it up that way.

First, it's important to realize the cookie itself isn't stored in session store (i.e. Redis in your case). What's stored is the representation of session itself, along with its attributes.

Besides session storage, other important aspect of session management is the correlation of user's HTTP request with the stored session. With Spring Session's Servlet API support this is the responsibility of HttpSessionIdResolver, and by default Spring Session uses cookie based implementation i.e. CookieHttpSessionIdResolver. There's also an HTTP header based implementation in HeaderHttpSessionIdResolver. I'm stating this because it's important to realize that session storage are distinct concerns that operate on different levels.

Now, regarding the CookieHttpSessionIdResolver, it delegates cookie writing and reading concerns to CookieSerializer (with DefaultCookieSerializer being the... well, default implementation). According to its configuration, DefaultCookieSerializer will respect a number of options when writing and reading session cookies i.e. cookie name, whether to Base64 encode cookie value, whether to use httpOnly cookie directive etc.

However, I cannot get server affinity because when I debug a HttpServletRequest as it comes into my Spring app, the HttpServletRequest.getSession().getId() doesn't have the jvmRoute in it (although the hex number matches what I see in Chrome), and this is what I pass to the Talend job.

This is the part that I don't understand - if you're able to resolve HttpSession from the current HttpServletRequest then you know what jvmRoute it's bound to right? It's the jvmRoute of the current JVM, otherwise session wouldn't be resolved HttpServletRequest in handled by this JVM.

What's different between the Spring Session and Tomcat's session management, is that with Tomcat the jvmRoute is session id generation related concern while with Spring Session the jvmRoute is used in the context of session cookie serialization.



来源:https://stackoverflow.com/questions/51868693/springsession-defaultcookieserializer-setjvmroute-works-but-httpservletrequest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!