本文介绍了SpringSession DefaultCookieSerializer.setJvmRoute 有效,但 HttpServletRequest 没有所需的 jvmRoute的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在我的旧 Spring MVC 应用程序中使用 Redis 实现了 Spring Session.我还使用了 DefaultCookieSerializer 来设置 jvmRoute,因为我需要一些服务器关联才能运行 Talend 作业.

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.

当我运行前端并在 Chrome 中检查页面时,我看到 jvmRoute 附加到会话中.如果我将其从node1"编辑为node2",会话将被保留.如果我重新部署服务器并在部署期间发出请求,我会被重定向到集群中的另一个节点,这意味着 Spring Sessions 运行良好.

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.

但是,我无法获得服务器关联,因为当我调试 HttpServletRequest 进入我的 Spring 应用程序时,HttpServletRequest.getSession().getId() 没有t 中有 jvmRoute(尽管十六进制数与我在 Chrome 中看到的相匹配),这就是我传递给 Talend 作业的内容.

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.

如果我恢复到 Tomcat 会话并在 server.xml 的引擎组件中设置 jvmRoute,我会看到 jvmRoute 附加到Chrome 中和调试代码时的会话 ID.

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.

DefaultCookieSerializer 到底做了什么?我认为它会在创建 cookie 时对其进行编辑,这就是 cookie 存储在 Redis 中的方式.因此,如果您以这种方式进行设置,那么在创建之后对该 cookie 的任何使用都应该附加 jmvRoute.

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.

推荐答案

首先,重要的是要意识到 cookie 本身并不存储在会话存储中(即在您的情况下是 Redis).存储的是会话本身及其属性的表示.

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.

除了会话存储之外,会话管理的另一个重要方面是用户的 HTTP 请求与存储的会话的关联.有了 Spring Session 的 Servlet API 支持,这是 HttpSessionIdResolver 的责任,默认情况下 Spring Session 使用基于 cookie 的实现,即 CookieHttpSessionIdResolver.HeaderHttpSessionIdResolver 中还有一个基于 HTTP 标头的实现.我之所以这么说是因为重要的是要意识到会话存储是在不同级别上运行的不同关注点.

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.

现在,关于 CookieHttpSessionIdResolver,它将 cookie 写入和读取问题委托给 CookieSerializer(DefaultCookieSerializer 是......好吧,默认执行).根据其配置,DefaultCookieSerializer 在写入和读取会话 cookie 时会考虑多个选项,即 cookie 名称、是否对 cookie 值进行 Base64 编码、是否使用 httpOnly cookie 指令等.

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.

但是,我无法获得服务器关联,因为当我调试 HttpServletRequest 进入我的 Spring 应用程序时,HttpServletRequest.getSession().getId() 中没有 jvmRoute(尽管十六进制数与我的匹配)在 Chrome 中查看),这就是我传递给 Talend 作业的内容.

这是我不明白的部分 - 如果你能够从当前的 HttpServletRequest 解析 HttpSession 那么你就知道什么是 jvmRoute 它一定对吗?它是当前 JVM 的 jvmRoute,否则 session 不会被解析 HttpServletRequest 由这个 JVM 处理.

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.

Spring Session 和 Tomcat 的会话管理的不同之处在于,对于 Tomcat,jvmRoute会话 id 生成相关问题 而对于 Spring Session,jvmRoute 用于会话 cookie 序列化的上下文中.

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.

这篇关于SpringSession DefaultCookieSerializer.setJvmRoute 有效,但 HttpServletRequest 没有所需的 jvmRoute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-26 18:00