如何在Google App Engine Java应用程序之间共享模块之间的会话?
当我通过模块A中的HttpSession
在会话中存储某些内容时:
HttpSession session = req.getSession(true); session.setAttribute("username", "Eng.Fouad");
然后我尝试从模块B中检索此信息(在同一浏览器会话期间):
HttpSession session = req.getSession(true); String username = session.getAttribute("username"); // null!
我将null
作为值,这意味着不同的会话。
如何在GAE中跨多个模块共享会话?
旧答案,我认为它不能很好地工作:
我一直试图解决这个问题好几个星期。 事实certificate,模块不共享会话,因为不同子域的cookie是不同的(module1.apphost.com cookies!= module2.apphost.com cookies)。 要解决此问题,只需在每个模块的web.xml
中设置cookie域:
org.mortbay.jetty.servlet.SessionDomain .apphost.com org.mortbay.jetty.servlet.SessionPath / org.mortbay.jetty.servlet.SessionURL none ...
额外:
以下是可以与Jetty cookie一起使用的所有init参数的列表:
编辑:开发环境的解决方法:
- 使每个模块的端口固定(使用JVM arg
-Dcom.google.appengine.devappserver_module.{module_name}.port=8081
)。 例如,module1始终托管在localhost:8888,而module2始终托管在localhost:8889。 看到这个答案 。 - 使用Fiddler将localhost与每个模块的端口绑定到自定义域。 例如,moule1.gaelocal.com指向localhost:8888,moule2.gaelocal.com指向localhost:8889。 看到这个答案 。
- 更新每个模块的
web.xml
并将.apphost.com
替换为.gaelocal.com
(或者只为两个环境使用.apphost.com
)。
您可以实现HttpServletFilter和HttpSessionListener的组合,这些组合可以在两个webapp上同步。 当请求修改会话状态时,将其保存到持久性存储(db),并且对于每个请求,检查会话对象是否与db最新。
请注意,这需要在同一个域下提供Web应用程序(例如:mydomain.com/webapp1和mydomain.com/webapp2)。 否则,浏览器将不会传递JSESSIONID cookie。
有一个现成的解决方案,如Hazelcast 。 它专为负载平衡/故障转移而设计,但您可以将其用于预期目的。
另外考虑使用HttpSession的可能性是错误的架构设计。 也许您应该使用数据库/ API进行交易?
HttpSession旨在用于monolithich环境,其中servlet容器直接与单个客户端联系。 一个实现建议是使用数据库API来存储客户端会话的当前状态。 由于您使用的是GAE,因此我想到了Google的数据存储区。
https://cloud.google.com/appengine/docs/java/gettingstarted/usingdatastore
我只是个初学者。 但您仍然可以尝试在配置文件中为cookie设置域并从那里检索会话。
root_path /portal ... ... true COOKIE
我希望这有帮助。
可能这个链接对你有帮助。
共享会话数据之间-2-亚结构域
- 如何将Jetty和Jersey嵌入到我的Java应用程序中
- Jersey错误JAXBStringReaderProviders $ RootElementProvider
- 一旦队列填满,WebSocket异步发送可能导致阻止发送
- Jetty Classpath问题
- Jetty / SOLR管理员面板密码
- 在docker热部署简单的应用程序
- Okhttp android Websocket和Jetty Server连接SSL
- Jetty mysql连接池配置错误:javax.naming.NameNotFoundException; 剩余名称’env / jdbc / —(mysql 5.0 + jetty 7.0.1)
- JAVA-生成预定的JSON