2009-07-17 68 views
11

我有兩種不同的webapps在一臺服務器上運行,使用不同的端口。他們都運行Java的Jetty servlet容器,因此他們都使用名爲JSESSIONID的cookie參數來跟蹤會話ID。這兩個webapps正在爭奪會話ID。JSESSIONID在同一ip但不同端口上的兩臺服務器之間的衝突

  • 打開Firefox的標籤,並轉到WebApp1
  • WebApp1的HTTP響應有一個Set-Cookie頭JSESSIONID = 1
  • 火狐現在有JSESSIONID一個Cookie標頭中的所有= 1是HTTP請求WebApp1
  • 打開第二個Firefox標籤,並轉到webapp2的
  • 的HTTP reqeust到webapp2的也有JSESSIONID = 1 Cookie頭,但在的doGet,當我打電話req.getSession(false);我得到null。如果我呼叫req.getSession(true),我得到一個新的會話對象,但是然後來自WebApp2的HTTP響應具有一個帶有JSESSIONID = 20的set-cookie頭。現在,WebApp2有一個工作會話,但WebApp1的會話不見了。去WebApp1會給我一個新的會話,吹走WebApp2的會話。
  • 永遠繼續下去

所以Session是每個Web應用程序之間的抖動。如果已經定義了JSESSIONID cookie,我真的很希望req.getSession(false)能夠返回有效的會話。

一個選擇是基本上用HashMap和Cookie重新實現Session框架,這個框架叫做WEBAPP1SESSIONID和WEBAPP2SESSIONID,但這很糟糕,並且意味着我不得不將新會話內容破解到ActionServlet和其他一些地方。

這一定是別人遇到的問題。 Jetty的HttpServletRequest.getSession(boolean)只是蹩腳的?

回答

2

我有一個類似的問題:在不同端口的本地主機上的同一個應用程序的一個或多個實例,在應用程序啓動時選擇,每個實例都使用它自己的碼頭實例。

一段時間後,我想出了這個:

  • 等待碼頭初始化
  • 使用碼頭的SocketManager得到端口(socketManager.getLocalPort()
  • 通過SessionManager (sessionHandler.getSessionManager().setSessionCookie(String))設置cookie的名字

這樣我每個實例都有一個不同的cookie名稱 - 因此不再有干擾。

0

這是正確的行爲。您可以將兩個Web應用程序放置到不同的域或不同的路徑。

0

我相信你也可以設置jsessionid的cookie路徑。

3

這不是Jetty的問題,它是如何定義cookie規範的。除了名稱/值對之外,Cookie還可能包含到期日期,路徑,域名以及cookie是否安全(即僅用於SSL連接)。端口號沒有列在上面;-)所以你需要改變路徑或域名,正如stepancheg在他的回答中所說的那樣。

+0

我的問題是,當碼頭去創建一個新的會話,在默認情況下,它甚至不嘗試使用JSESSIONID的現有價值。它只是爲它選擇一個新的價值。如果它重複使用現有的,那麼我的兩個Jetty實例可以很好玩。 – 2009-07-20 19:27:47

1

我一直在挖,我發現在AbstractSessionManager,有一種方法稱爲getCrossContextSessionIDs()。如果返回true,那麼在創建新會話時,Jetty將首先檢查是否設置了JSESSIONID,並嘗試使用該現有的會話ID。我想我可以在啓動時使用某種java屬性將值設置爲true

在進一步的挖掘中,如果我在同一個Jetty的不同上下文中運行兩個webapps(因此,跨上下文),這隻會幫助我。創建新的Session對象時,會選擇一個新的JSESSIONID值。如果getCrossContextSessionIDs()返回true,那麼它將檢查當前的JSESSIONID值是否由此Jetty(包括所有其他上下文)創建,如果是,它將重用它。

因爲我正在處理在兩個不同端口上運行的兩個不同Jetty實例,所以我需要破解Jetty的源代碼而不是執行該檢查,或者只是製作自己的類似會話的框架。

+0

這聽起來像你必須堅持使用Jetty--我不認爲這個解決方案可以與其他servlet容器一起工作。希望你永遠不需要切換:-) – 2009-07-20 19:45:13

2

在我們的案例中,我們使用的是Tomcat,因此解決方案是在每個實例上使用不同的會話cookie名稱。

context.xml這樣做

<Context sessionCookieName="JSessionId_8080"> 
相關問題