2012-03-09 41 views
0

我不是太肯定的,我試圖達到要求的可行性,但在這裏是怎麼一回事:Servlet充當代理:如何轉發會話?

  • 我創建了充當代理的servlet。它接收RESTful調用,然後調用遠程服務器(節點)上的另一個RESTful服務。
  • 轉發是通過HTTPClient而不是通過請求分派器來實現的。我基本上發出一個新的HTTP請求到遠程服務器。
  • 當第一個服務器(代理服務器)接收到該呼叫時,該請求(HttpServletRequest)具有與其關聯的會話。 HTTPSessionisNew()屬性爲false。
  • 當呼叫被轉發並且遠程服務器接收到呼叫時,會話將成爲一個全新的會話。

我想基本上找到一種方法將會話轉發到遠程服務器以及。

爲了更精確: 是否可以簡單地從HttpServletRequest得到一個會話,並把它變成一個新創建的HTTP請求的會話(通過HTTPClient)?

回答

2

這取決於您的遠程WS如何維護會話。例如,如果它使用cookies(Tomcat在其他技術中做到這一點),那麼轉發傳入的頭文件應該可以幫助你實現這一點(確保你提到你接受cookies,但是我默認情況下HTTPClient會這樣做)。 現在,如果它基於URL中的參數,那麼您應該嘗試重現該行爲。

1

如果兩個節點(代理和服務)是不屬於應用程序集羣的單獨進程,那麼可能不是。

servlet容器通常管理HttpSession。如果您將請求轉發給由另一個容器託管的另一個服務,那麼您將擁有不同的會話對象。

如果兩個節點是集羣的一部分,那麼通常可以通過多種機制(在內存複製,數據庫同步等中)在集羣中的節點之間共享會話。

另一種選擇是將會話數據外部化爲類似Redis,Memcached,Coherence等的應用程序服務器。這些應用程序服務器具有對這種過程的可插拔支持。我相信在這種情況下,應用程序服務器節點不一定必須是羣集的一方纔能共享會話數據。

0

當我問這個問題時,我缺乏一些會話處理的基礎知識。一些研究和這裏討論後是我得到:

  • 基本上,會議由JSESSIONID變量處理。
  • JSESSIONID在請求到達服務器時自動創建(可以關閉)。
  • 它在響應頭中被髮回。
  • 遠程服務器認爲它是新會話的原因是因爲該請求沒有此JSESSIONID集。

  • 代理執行以下操作以確保該會話被轉發:

    1. 當傳入請求進入;創建並存儲JSESSIONID
    2. 向遠程服務器發出新請求。
    3. 從遠程服務器解壓縮響應頭並提取JSESSIONID
    4. 維護客戶端JSESSIONID和遠程服務器JSESSIONID的映射。
    5. 對於以下任何請求,請使用此映射將請求發送到遠程服務器。

基本上,代理確實從客戶端的JSESSIONID到遠程服務器的JSESSIONID的映射。這樣,會話就被轉發到遠程服務器。