Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同一ip但不同端口上的两台服务器之间的JSESSIONID冲突_Java_Http_Cookies_Jetty - Fatal编程技术网

Java 同一ip但不同端口上的两台服务器之间的JSESSIONID冲突

Java 同一ip但不同端口上的两台服务器之间的JSESSIONID冲突,java,http,cookies,jetty,Java,Http,Cookies,Jetty,我曾经遇到过这样一种情况:在一台服务器上运行两个不同的Web应用程序,使用不同的端口。他们都在运行Java的Jetty servlet容器,所以他们都使用一个名为JSESSIONID的cookie参数来跟踪会话id。这两个Web应用程序正在为会话id而争吵 打开Firefox选项卡,然后转到WebApp1 WebApp1的HTTP响应有一个设置cookie头,其JSESSIONID=1 Firefox现在在对WebApp1的所有HTTP请求中都有一个JSESSIONID=1的Cookie头 打

我曾经遇到过这样一种情况:在一台服务器上运行两个不同的Web应用程序,使用不同的端口。他们都在运行Java的Jetty servlet容器,所以他们都使用一个名为JSESSIONID的cookie参数来跟踪会话id。这两个Web应用程序正在为会话id而争吵

  • 打开Firefox选项卡,然后转到WebApp1
  • WebApp1的HTTP响应有一个设置cookie头,其JSESSIONID=1
  • Firefox现在在对WebApp1的所有HTTP请求中都有一个JSESSIONID=1的Cookie头
  • 打开第二个Firefox选项卡,然后转到WebApp2
  • WebApp2的HTTP请求也有一个Cookie头,JSESSIONID=1,但在doGet中,当我调用
    req.getSession(false)时我得到
    null
    。如果我调用
    req.getSession(true)
    我会得到一个新的Session对象,但是来自WebApp2的HTTP响应有一个setcookie头,其JSESSIONID=20
  • 现在,WebApp2有一个工作会话,但WebApp1的会话已不存在。转到WebApp1将给我一个新的会话,取消WebApp2的会话
  • 永续
因此,会话在每个web应用程序之间来回切换。如果已经定义了JSESSIONID cookie,我非常希望
req.getSession(false)
返回一个有效的会话

一个选项是基本上用一个HashMap和一个叫做WEBAPP1SESSIONID和WEBAPP2SESSIONID的cookies重新实现会话框架,但这太糟糕了,这意味着我必须将新的会话内容破解到ActionServlet和其他一些地方


这一定是其他人遇到的问题。Jetty的
HttpServletRequest.getSession(布尔)
就是垃圾吗?

这是正确的行为。您可以将两个Web应用程序放置到不同的域,或通过不同的路径。

我相信您也可以设置jsessionid cookie路径。

这不是Jetty的问题,而是cookie规范的定义方式。除了名称/值对之外,cookie还可能包含过期日期、路径、域名以及cookie是否安全(即仅用于SSL连接)。上面未列出端口号;-)因此,你需要改变路径或域,正如stepancheg在他的回答中所说

我一直在挖掘,发现在
AbstractSessionManager
中有一个名为
GetCrossContextSessionId()的方法。如果它返回
true
,那么在创建新会话时,Jetty将首先检查是否设置了JSESSIONID,并尝试使用该现有会话id。我想我可以在启动时使用某种java属性将值设置为
true

进一步挖掘,只有当我在同一个Jetty的不同上下文中运行两个webapp(因此,跨上下文)时,这才有助于我。创建新的
会话
对象时,会选择一个新的
JSESSIONID
值。如果
getCrossContextSessionId()
返回
true
,则它将检查当前的
JSESSIONID
值是否由该Jetty(包括所有其他上下文)创建,如果是,它将重用它


由于我正在处理两个不同端口上运行的两个不同Jetty实例,我需要破解Jetty的源代码以不进行该检查,或者只是创建自己的类似于会话的框架。

我遇到了一个类似的问题:本地主机上不同端口上的同一应用程序的一个或多个实例,在应用程序启动时选择,每个都使用自己的jetty实例

过了一会儿,我想到了这个:

  • 等待jetty初始化
  • 使用jetty的SocketManager获取端口(
    SocketManager.getLocalPort()
  • 通过SessionManager
    (sessionHandler.getSessionManager().setSessionCookie(String)
    )设置cookie名称

这样,每个实例的cookie名称就不同了,因此不再有干扰。

在我们的例子中,我们使用的是Tomcat,所以解决方案是在每个实例上使用不同的会话cookie名称

context.xml
中执行以下操作

<Context sessionCookieName="JSessionId_8080">


我的问题是,在Jetty创建新会话时,默认情况下,它甚至不尝试使用JSESSIONID的现有值。它只是为它选择了一个新的值。如果它重用现有的,那么我的两个Jetty实例就可以很好地发挥作用了。听起来你必须坚持使用Jetty——我不认为这个解决方案可以与其他servlet容器一起使用。希望你永远不需要切换:-)你是对的。我们正在考虑修改Jetty的代码作为短期修复。从长远来看,我们要么使用不同的cookie实现自己的会话管理,要么在实现SSO系统时一切都会改变。