Java 有什么方法可以在tomcat中的不同应用程序之间共享会话状态?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/665941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Any way to share session state between different applications in tomcat?
提问by Serxipc
We want to split a working application in two different .war
files in order to be able to update one app without affecting the other. Each webapp will have different a UI, different users and different deploy schedule.
我们希望将一个工作应用程序拆分为两个不同的.war
文件,以便能够在不影响另一个应用程序的情况下更新一个应用程序。每个 webapp 都有不同的 UI、不同的用户和不同的部署时间表。
The easiest path seems to be sharing the same session, so if app A set session.setAttribute("foo", "bar")
app B will be able to see it.
最简单的路径似乎是共享同一个会话,因此如果应用程序 A 设置session.setAttribute("foo", "bar")
应用程序 B 将能够看到它。
Is there a way to share the HttpSession
state for both apps in the same Tomcat instance?
有没有办法HttpSession
在同一个 Tomcat 实例中共享两个应用程序的状态?
Our app is running on a dedicated Tomcat 5.5, there are no other apps running on the same tomcat instance, so any security concerns regarding the session sharing are not a problem. We're running multiple Tomcat instances, but the balancer is using sticky sessions.
我们的应用程序运行在专用的 Tomcat 5.5 上,没有其他应用程序运行在同一个 tomcat 实例上,因此任何有关会话共享的安全问题都不是问题。我们正在运行多个 Tomcat 实例,但平衡器正在使用粘性会话。
If it's not possible or this session sharingis a really bad idea please leave a comment.
如果不可能或此会话共享是一个非常糟糕的主意,请发表评论。
采纳答案by Aaron Digulla
You should not share HttpSession; but you can share other objects. For example, you can register an object via JNDIand access the same object in all your apps (databases use this to pool connections).
你不应该共享 HttpSession;但您可以共享其他对象。例如,您可以通过 JNDI 注册一个对象并在您的所有应用程序中访问同一个对象(数据库使用它来池连接)。
回答by Kris
If the to webapps are so closely coupled that they need to share objects why are you splitting it in two? Even if you manage them somewhat independently any decent build management system should be able to create a single WAR file for deployment.
如果 to webapps 耦合得如此紧密以至于它们需要共享对象,为什么要将其一分为二?即使您在某种程度上独立管理它们,任何体面的构建管理系统也应该能够创建一个用于部署的 WAR 文件。
A solution like Aaron suggest with JNDI will work, but only if both webapps are running on the same server. If the units are tightly coupled and you are going to be running it on the same server anyway ... might as well have a single WAR
像 Aaron 建议的 JNDI 解决方案将起作用,但前提是两个 web 应用程序都在同一台服务器上运行。如果这些单元是紧密耦合的,并且无论如何你都将在同一台服务器上运行它......不妨有一个单一的 WAR
If you really do want them to stand independently I'd seriously examine the data exchange between the two. Ideally you'd want them to only share relevant data with one another. This data could be passed back and forth via POST (or GET if more appropriate) parameters, you might even consider using cookies.
如果您真的希望它们独立站立,我会认真检查两者之间的数据交换。理想情况下,您希望他们仅彼此共享相关数据。这些数据可以通过 POST(或 GET,如果更合适)参数来回传递,您甚至可以考虑使用 cookie。
回答by Alex Miller
One thing to be aware of is that two web apps will use different classloaders. If you want to share objects, they need to use the same version of the class from the same classloader (or else you will get LinkageErrors). That means either putting them in a classloader shared by both web apps (system classpath for example) OR using serialization to effectively drain and reconstitute the object in the right classloader with the correct version of the class.
需要注意的一件事是两个 Web 应用程序将使用不同的类加载器。如果你想共享对象,他们需要使用来自同一个类加载器的相同版本的类(否则你会得到 LinkageErrors)。这意味着要么将它们放在由两个 Web 应用程序共享的类加载器中(例如系统类路径),要么使用序列化来有效地在正确的类加载器中使用正确版本的类排空和重构对象。
回答by cherouvim
You should not split your app that way in order by have high availability. You could deploy the whole app on many tomcat instances.
您不应该通过高可用性来按顺序拆分您的应用程序。您可以在许多 tomcat 实例上部署整个应用程序。
回答by Ray Hulha
One way of doing this is described in this blog post: Session sharing in Apache Tomcat
此博客文章中描述了一种方法:Apache Tomcat 中的会话共享
Summary: Add emptySessionPath to the Connector configuration and crossContext to the Context
总结:在Connector配置中添加emptySessionPath,在Context中添加crossContext
回答by Qazi
You can do by taking servlet context by your context root.
您可以通过上下文根获取 servlet 上下文来完成。
For retrieving variable.
用于检索变量。
request.getSession().getServletContext().getContext("/{applicationContextRoot}").getAttribute(variableName)
For setting variable:
设置变量:
request.getSession().getServletContext().getContext("/{applicationContextRoot}").setAttribute(variableName,variableValue)
Note:Both the applications should deployed in the same server.
注意:这两个应用程序应该部署在同一台服务器上。
Pls let me know if you find any problem
如果您发现任何问题,请告诉我
回答by Luís Soares
If you want to use Spring, there's a project called Spring Session: https://github.com/spring-projects/spring-session
如果你想使用 Spring,有一个名为Spring Session的项目:https: //github.com/spring-projects/spring-session
Quoting: "HttpSession - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way"
引用:“HttpSession - 允许以应用程序容器(即 Tomcat)中立方式替换 HttpSession”
回答by rohith
Tomcat 8 :
i had to do : <Context crossContext="true" sessionCookiePath="/">
in conf/context.xml
Tomcat 8:我必须这样做:<Context crossContext="true" sessionCookiePath="/">
在 conf/context.xml 中
more details on config attributes here
有关配置属性的更多详细信息here
and then to set the value(like @Qazi's answer):
然后设置值(如@Qazi 的回答):
ServletContext servletContext =request.getSession().getServletContext().getContext("contextPath")
servletContext.setAttribute(variableName,variableValue)
to get the value:
获取值:
ServletContext servletContext =request.getSession().getServletContext().getContext("contextPath")
servletContext.getAttribute("user");
回答by Amogh
I developed session state serverfor tomcat using python.
我使用 python 为 tomcat开发了会话状态服务器。
Due to this I don't need to change the code already written for creating/accessing and destroying session. Also as there is separate server/service which is handling and storing session so not master cluster is needed. There is no session replication (as in tomcat clustering) in this case, rather this is session sharing between web farming.
因此,我不需要更改已经为创建/访问和销毁会话编写的代码。此外,由于有单独的服务器/服务处理和存储会话,因此不需要主集群。在这种情况下没有会话复制(如在 tomcat 集群中),而是网络农场之间的会话共享。
回答by flavio.donze
For Tomcat 8 I use the following configuration to share a session across 2 webapps:
对于 Tomcat 8,我使用以下配置在 2 个 web 应用程序之间共享会话:
conf/context.xml
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>
I deploy the same simple webapp twice log.warand log2.war:
我部署了相同的简单 webapp 两次log.war和log2.war:
/log
/log2
I can now log-in to /log
and have the user displayed in /log2
, this does not work with the tomcat default configuration.
我现在可以登录/log
并显示用户/log2
,这不适用于 tomcat 默认配置。
The session value is set and read:
会话值被设置和读取:
HttpSession session=request.getSession();
session.setAttribute("name",name);
HttpSession session=request.getSession(false);
String name=(String)session.getAttribute("name");
I used this project as example: https://www.javatpoint.com/servlet-http-session-login-and-logout-example
我以这个项目为例:https: //www.javatpoint.com/servlet-http-session-login-and-logout-example
Most examples/solutions use a in-memory database which requires more setup work:
大多数示例/解决方案使用需要更多设置工作的内存数据库: