4

HttpSession当我通过模块A在会话中存储一些东西时:

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 将 localhost 与每个模块的端口绑定到自定义域。例如,moule1.gaelocal.com 指向 localhost:8888,moule2.gaelocal.com 指向 localhost:8889。看到这个答案
  3. 更新web.xml每个模块并替换.apphost.com.gaelocal.com(或仅.apphost.com用于两种环境)。

4

3 回答 3

1

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

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

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

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

于 2015-01-06T22:25:29.293 回答
0

我只是一个初学者。但是您仍然可以尝试在配置文件中设置 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 个子域之间共享会话数据

于 2015-01-13T05:08:55.890 回答
0

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

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

于 2015-01-06T22:30:41.247 回答