web服務器為每一個瀏覽器實例對應一個session。這個session有自己的一個獨立id,這個id保存在瀏覽器的cookie中(這個cookie貌似隨着這個瀏覽器實例的關閉而清除),訪問web服務器的時候,web服務會根據你cookie中的sessionId來決定重新創建一個session還是使用已經存在的session。
如果使用桌面的ie圖標打開一個IE窗口,這個窗口屬於一個新的瀏覽器實例(其中不包含sessionid信息),這時候用這個IE訪問web服務器的時候web服務器會為這個瀏覽器實例新創建一個httpsession,sessionId也是新的(sessionId保存到本地的cookie中),不會對你以前打開的窗口中的session產生覆蓋,關閉ie窗口的時候cookie中的信息也就清除掉了。
如果是在打開的ie窗口中按“ctrl+n”打開一個ie窗口,這個窗口於剛才的窗口是同一個實例,與剛才的窗口共用session,所有的同一個ie實例的窗口都關掉后,會清除掉sessionId。
補充一點,可以通過人為的輸入參數sessionId通知web服務器你使用的是哪個session(如果服務器存在這個session的話)。
*****************************************************************************************************************************************
單點登錄(有別於SSO:Single Sign On),首先解釋一下對項目需求中的單點登錄的理解:一個用戶帳號成功登錄后,在該次session還未失效之前,不能在其他機器上登錄同一個帳號,這有點類似與QQ只能在同一台計算機上登錄。好了,如何實現呢?現在分析一下:一次登錄也就是一次會話(Session),那么我們可以很容易聯想到通過控制session來實現單點登錄,我的設想是這樣的,登錄后將用戶信息保存到session中,如果此時在另外一台機器上一個相同的帳號請求登錄,通過遍歷Web服務中所有session並判斷其中是否包含同樣的用戶信息,通過這樣的判斷,在另一台機器上登錄該帳號是不成功的。
上面已經提到了,需要通過控制session,對web服務中所有session進行遍歷操作,那么你肯定會想到application這個大對象了(當然你也可以采用緩存或者數據庫),具體實現方法是這樣的,首先在application中創建一個List<HttpSession>,用來保存每一次會話(session)對象,系統在驗證用戶登錄請求時,通過遍歷該list並加以判斷,最后決定是否讓該用戶成功登錄。OK,需求和設計都在上面了,接下來就是編碼工作了哈。不過在這里還需要考慮幾個問題:
1、如果登錄后關閉了瀏覽器,想立即打開一個新的瀏覽器並登錄將會失敗,因為前一次登錄后的session還沒銷毀,你需要等其銷毀后方可再次登錄成功,這種問題如何解決???哈哈,你是不是已經想到要用javascript處理一下下,即在關閉瀏覽器的時候觸發一個事件,該事件就是通知來銷毀當前session的。
2、第二個問題其實是接上一個問題而討論的,用javascript觸發瀏覽器關閉事件並不是一個好辦法,因為有很多因素可能導致這個事件觸發不成功,還有Firefox和IE這兩個東東意見有時候並不統一,最后有一個比較可惡的問題就是,我在同一台機器上不能打開兩個瀏覽器窗口去登錄相同的帳號,因為一個瀏覽器對應一個session啊!這就是為什么我在文章一開始要引用一些基本知識。
既然問題很嚴重,那就動腦殼去想辦法啊!我在這里自言自語了半天,我不打算用中文繼續講下去了,直接code上場吧:
login.jsp