簡體   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