Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.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 有没有办法在tomcat中的不同应用程序之间共享会话状态?_Java_Session_Tomcat_Jakarta Ee - Fatal编程技术网

Java 有没有办法在tomcat中的不同应用程序之间共享会话状态?

Java 有没有办法在tomcat中的不同应用程序之间共享会话状态?,java,session,tomcat,jakarta-ee,Java,Session,Tomcat,Jakarta Ee,我们希望将一个工作应用程序拆分为两个不同的.war文件,以便能够在不影响另一个应用程序的情况下更新一个应用程序。每个webapp都有不同的UI、不同的用户和不同的部署计划 最简单的路径似乎是共享同一个会话,因此如果应用程序A设置session.setAttribute(“foo”,“bar”)app B将能够看到它 有没有办法在同一个Tomcat实例中共享两个应用程序的HttpSession状态 我们的应用程序运行在一个专用的Tomcat 5.5上,没有其他应用程序运行在同一个Tomcat实例上

我们希望将一个工作应用程序拆分为两个不同的
.war
文件,以便能够在不影响另一个应用程序的情况下更新一个应用程序。每个webapp都有不同的UI、不同的用户和不同的部署计划

最简单的路径似乎是共享同一个会话,因此如果应用程序A设置
session.setAttribute(“foo”,“bar”)
app B将能够看到它

有没有办法在同一个Tomcat实例中共享两个应用程序的
HttpSession
状态

我们的应用程序运行在一个专用的Tomcat 5.5上,没有其他应用程序运行在同一个Tomcat实例上,因此关于会话共享的任何安全问题都不是问题。我们正在运行多个Tomcat实例,但平衡器正在使用粘性会话


如果不可能或此会话共享是一个非常糟糕的主意,请留下评论。

您不应该共享HttpSession;但您可以共享其他对象。例如,您可以在所有应用程序中访问同一对象(数据库使用它来共享连接)。

如果两个Web应用程序紧密耦合,需要共享对象,为什么要将其拆分为两个?即使您在某种程度上独立地管理它们,任何合适的构建管理系统都应该能够为部署创建单个WAR文件

Aaron建议使用JNDI这样的解决方案是可行的,但前提是两个Web应用程序都在同一台服务器上运行。如果这些单元是紧密耦合的,并且您将在同一台服务器上运行它。。。还不如打一场战争


如果你真的希望它们独立存在,我会认真研究两者之间的数据交换。理想情况下,您希望他们只彼此共享相关数据。这些数据可以通过POST(或者得到更合适的参数)来来回传递,甚至可以考虑使用Cookie。 需要注意的一点是,两个web应用程序将使用不同的类加载器。如果您想共享对象,它们需要使用来自同一类加载器的同一版本的类(否则您将得到LinkageErrors)。这意味着要么将它们放在两个web应用程序共享的类加载器中(例如,系统类路径),要么使用序列化有效地使用正确版本的类在正确的类加载器中耗尽并重新构造对象

您不应该为了获得高可用性而以这种方式拆分应用程序。您可以在许多tomcat实例上部署整个应用程序。

本文介绍了一种方法:

摘要:将emptySessionPath添加到连接器配置中,并将crossContext添加到上下文中


您可以通过上下文根获取servlet上下文来实现

用于检索变量

request.getSession().getServletContext().getContext("/{applicationContextRoot}").getAttribute(variableName)
对于设置变量:

request.getSession().getServletContext().getContext("/{applicationContextRoot}").setAttribute(variableName,variableValue)
注意:两个应用程序应部署在同一台服务器上


如果您发现任何问题,请告诉我如果您想使用Spring,有一个名为的项目:

引用:“HttpSession-允许以中性方式替换应用程序容器(即Tomcat)中的HttpSession”Tomcat 8: 我必须在conf/context.xml中执行:

有关配置属性的更多详细信息

然后设置值(如@Qazi的答案):

要获取值,请执行以下操作:

ServletContext servletContext =request.getSession().getServletContext().getContext("contextPath")
servletContext.getAttribute("user"); 
我使用python为tomcat开发


因此,我不需要更改为创建/访问和销毁会话而编写的代码。另外,由于有单独的服务器/服务处理和存储会话,因此不需要主集群。在这种情况下,没有会话复制(如tomcat集群),而是web farming之间的会话共享。

对于tomcat 8,我使用以下配置跨2个web应用共享会话:


conf/context.xml

<Context sessionCookiePath="/">
    <Valve className="org.apache.catalina.valves.PersistentValve"/>
    <Manager className="org.apache.catalina.session.PersistentManager">
        <Store className="org.apache.catalina.session.FileStore" directory="${catalina.base}/temp/sessions"/>
    </Manager>
    ...
</Context>
我现在可以登录到
/log
,并将用户显示在
/log2
中,这不适用于tomcat默认配置

设置并读取会话值:

HttpSession session=request.getSession();  
session.setAttribute("name",name);

HttpSession session=request.getSession(false);  
String name=(String)session.getAttribute("name");  
我以这个项目为例:

大多数示例/解决方案使用内存中数据库,这需要更多的设置工作:


    • conf/context.xml

      <Context sessionCookiePath="/">
        ...
        <Manager className="org.redisson.tomcat.RedissonSessionManager"
                     configPath="${catalina.base}/conf/redisson.yml"
                     readMode="REDIS" />
      </Context>
      
      singleServerConfig:
        address: "redis://<host>:6379"
      
      
      ...
      
      conf/redisson.yml

      <Context sessionCookiePath="/">
        ...
        <Manager className="org.redisson.tomcat.RedissonSessionManager"
                     configPath="${catalina.base}/conf/redisson.yml"
                     readMode="REDIS" />
      </Context>
      
      singleServerConfig:
        address: "redis://<host>:6379"
      
      singleServerConfig:
      地址:“redis://:6379”
      
      再贴现

      sessioncokiepath=“/”
      使Tomcat对不同的web应用程序使用相同的会话id。
      RedissonSessionManager
      将会话持久化到“共享空间”


      我无法在sharedcontext.xml中使用
      org.apache.catalina.session.FileStore
      PersistentManager
      获得预期的结果,我在后台过期监视器线程中面临会话反序列化问题。它无法反序列化会话,因为它使用的是公共类加载器,而类路径中没有webapp可序列化模型。从理论上讲,
      PersistentManager
      可以在web-INF/context.xml中分别为每个web应用程序配置(以具有适当的类路径),但我未能使其正常工作

      org.apache.catalina.session.JDBCStore
      PersistentManage
      很有希望,因为它公开了会话的
      last\u access
      列,因此不需要对
      会话数据进行反序列化,但它一直在保存
      app\u name
      ,导致相同的会话id被写入不同的web应用程序的不同行。因此,会话数据未存储在共享位置

      Spring会话有自己的创建会话id的方法。我无法找到强制Spring会话为不同的web应用创建相同会话id的解决方案

      具有核心tomcat会话id生成功能的解决方案(能够为不同的web应用程序和RedissonSessionManager生成相同的会话id)(它们使用会话id作为唯一键存储数据,并且