我有一个情况我有两个不同的webapps在一台服务器上运行,使用不同的端口。 他们都在运行Java的码头servlet容器,所以它们都使用名为JSESSIONID一个cookie参数跟踪会话ID。 这两个的webapps战斗在会话ID。
- 打开Firefox选项卡,然后转到WebApp1
- WebApp1的HTTP响应具有JSESSIONID = 1 set-cookie头
- 火狐现在有一个JSESSIONID cookie头部中的所有= 1是HTTP请求WebApp1
- 打开第二个Firefox标签,并转到webapp2的
- 的HTTP reqeust到webapp2的也具有JSESSIONID = 1一个Cookie报头,但在的doGet,当我打电话
req.getSession(false);
我得到null
。 如果我叫req.getSession(true)
我得到一个新的Session对象,但随后从webapp2的HTTP响应与JSESSIONID = 20一个Set-Cookie头 - 现在,webapp2的有一个工作会议,但WebApp1的会话了。 要WebApp1会给我一个新的会话,吹走webapp2的会话。
- 永远继续下去
因此,会议的每个Web应用程序之间的抖动。 我真的很喜欢的req.getSession(false)
到是否已存在定义的JSESSIONID的cookie返回一个有效的会话。
一种选择是基本上重新实现了一个名为WEBAPP1SESSIONID和WEBAPP2SESSIONID HashMap和饼干会议的框架,但很烂,而且意味着我将不得不破解新的Session的东西进入的ActionServlet和其他一些地方。
这一定是其他人都遇到过的问题。 是Jetty的HttpServletRequest.getSession(boolean)
只是蹩脚?
我有一个类似的问题:在不同的端口本地主机相同的应用,在应用choosen的一个或多个实例启动时,分别使用自己的码头实例。
过了一会儿,我想出了这一点:
- 等到码头初始化
- 使用码头的SocketManager得到端口(
socketManager.getLocalPort()
- 通过SessionManager设置cookie名称
(sessionHandler.getSessionManager().setSessionCookie(String)
)
这样一来,我为每个实例的差异cookie名称 - 因此没有干扰了。
这不是Jetty的问题,它的cookie规范是如何定义的。 旁边的名称/值对,一个cookie也可以包含过期日期,路径,一个域名和cookie是否是安全的(即,仅用于SSL连接)。 端口号未在上面列出;-)所以你需要改变路径或域名,如stepancheg他回答说。
在我们的例子中,我们使用的是Tomcat,因此该解决方案是在每个实例中使用不同的会话cookie的名字。
在context.xml
做这样的事情
<Context sessionCookieName="JSessionId_8080">
我一直在挖,而且我发现,在AbstractSessionManager
,有一个方法叫getCrossContextSessionIDs()
如果返回true
,创建一个新的会话那么当,码头将首先检查是否JSESSIONID设置,并尝试使用现有的会话ID。 我想我可以设置的值,以true
使用某种在启动Java属性的。
在进一步的挖掘,这只会帮助我,如果我运行在同一个码头(因此,跨上下文)的不同的上下文的web应用。 当创建一个新的Session
对象时,一个新的JSESSIONID
值被选择。 如果getCrossContextSessionIDs()
返回true
,那么它会检查当前JSESSIONID
值由该码头(包括所有其他情况下)创建,如果是,它会重新使用它。
因为我负责的两个不同的端口上运行两个不同的码头情况下,我需要破解Jetty的源那样做检查,或者只是让我自己的会话状框架。
这是正确的行为。 你可以把你的两个web应用到不同的领域,或通过不同的路径。
你也可以设置JSESSIONID cookie路径,我相信。