繁体   English   中英

如何在Google App Engine Java应用程序的模块之间共享会话?

[英]How to share sessions between modules on a Google App Engine Java application?

当我通过模块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中的多个模块之间共享会话?


我认为效果不佳的旧答案:

数周以来,我一直在努力解决这个问题。 事实证明,模块不共享会话,因为cookie在不同的子域中是不同的(module1.apphost.com cookie!= module2.apphost.com cookie)。 要解决此问题,只需在每个模块的 web.xml中设置cookie域:

 
 
 
 
  
  
  <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <context-param> <param-name>org.mortbay.jetty.servlet.SessionDomain</param-name> <param-value>.apphost.com</param-value> </context-param> <context-param> <param-name>org.mortbay.jetty.servlet.SessionPath</param-name> <param-value>/</param-value> </context-param> <context-param> <param-name>org.mortbay.jetty.servlet.SessionURL</param-name> <param-value>none</param-value> </context-param> ... </web-app>
 
 
  

额外:

这是可以与Jetty cookie一起使用的所有初始化参数的列表:

在此处输入图片说明


编辑:开发环境的解决方法:

  1. 固定每个模块的端口(使用JVM arg -Dcom.google.appengine.devappserver_module.{module_name}.port=8081 )。 例如,module1始终托管在localhost:8888,而module2始终托管在localhost:8889。 看到这个答案
  2. 使用Fiddler将本地主机和每个模块的端口绑定到自定义域。 例如,moule1.gaelocal.com指向localhost:8888,moule2.gaelocal.com指向localhost:8889。 看到这个答案
  3. 更新每个模块的 web.xml并将 .apphost.com替换为 .gaelocal.com (或在两种环境中仅使用 .apphost.com )。

您可以实现HttpServletFilter和HttpSessionListener的组合,从而在两个Web应用程序之间进行同步。 当请求修改会话状态时,将其保存到持久性存储(db),对于每个请求,检查会话对象是否与db更新。

请注意,这要求两个Web应用程序都必须在同一域下提供(例如:mydomain.com/webapp1和mydomain.com/webapp2)。 否则,浏览器将不会传递JSESSIONID cookie。

有一个现成的解决方案,例如Hazelcast 它是专为负载平衡/故障转移而设计的,但您可能可以将其用于预期的目的。

还考虑使用HttpSession的可能性是错误的体系结构设计。 也许您应该改为使用数据库/ API进行交易?

HttpSession适用于单片环境,其中Servlet容器直接与单个客户端联系。 一种实现建议是使用数据库API存储客户端会话的当前状态。 由于您使用的是GAE,因此请记住Google的数据存储区。

https://cloud.google.com/appengine/docs/java/gettingstarted/usingdatastore

我只是一个初学者。 但是您仍然可以尝试在配置文件中设置Cookie的域,并从中检索会话。

<context-param>
    <param-name>root_path</param-name>
    <param-value>/portal</param-value>  
</context-param>
...
...
<session-config>
    <cookie-config>
      <http-only>true</http-only>
    </cookie-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>

我希望这有帮助。

可能此链接对您有帮助。

在2个子域之间共享会话数据

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM