如何在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参数的列表:

在此处输入图像描述


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

  1. 使每个模块的端口固定(使用JVM arg -Dcom.google.appengine.devappserver_module.{module_name}.port=8081 )。 例如,module1始终托管在localhost:8888,而module2始终托管在localhost:8889。 看到这个答案 。
  2. 使用Fiddler将localhost与每个模块的端口绑定到自定义域。 例如,moule1.gaelocal.com指向localhost:8888,moule2.gaelocal.com指向localhost:8889。 看到这个答案 。
  3. 更新每个模块的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-亚结构域