最近在做登錄和權(quán)限控制模塊,用到了session,發(fā)現(xiàn)session的好多方法都不熟悉,而且以前也聽說過JsessionId 之類session竊取的事,
對這些一直都是一知半解。今天索性google了很多資料,先上sun的官網(wǎng)去看session的文檔了解一些方法,又找了別人關(guān)于session的看法。
總結(jié)如下:
1,session是什么? what
session經(jīng)常譯為會話,以打電話為例,從開始撥號到掛斷電話就是你會話的生存周期。
2,session 做什么用的 why?
首先舉個例子:
咖啡店舉行 消費滿5杯咖啡贈送一杯的活動,可每個人一次消費5杯的時候非常少。這時候有3種辦法:
1,店員看到每個顧客時都能記住其消費了多少杯,從而給其優(yōu)惠,這是協(xié)議本身具有狀態(tài)
2,給每個顧客一個卡片,上面記錄顧客的每次消費,這是客戶端保存狀態(tài)
3,給每個顧客一個卡片,卡片上只有一個編號,顧客每次的消費記錄在店里,這就是 服務(wù)端有狀態(tài)
而http本身是無狀態(tài)的,所以我們只能使用2,3中方法,來保存一些信息。
實際采用的是第3種方法,服務(wù)器段保存一次會話所有的信息,并生成一個唯一的id,這個id沒有規(guī)律而且不會重復(fù),將這個id傳回到客戶段,
保存到cookie中。每次訪問服務(wù)器時,客戶端都會偷偷將這個id傳到服務(wù)器,服務(wù)器根據(jù)id查到這次會話保存的內(nèi)容。就能實現(xiàn)會話中共享一些數(shù)據(jù)。
3,session怎樣創(chuàng)建和銷毀 ? how
session是保存在內(nèi)存中的,所以會有一些性能上的影響。因此本著這個原則,session是只有在使用到的時候才會被創(chuàng)建,如果始終沒有用到
session,這個session是永遠(yuǎn)不會被創(chuàng)建的。
比如: 訪問servlet ,只要你代碼中沒有 request.getSession()或request.getSession(true);這兩行是等價的,那session是不會創(chuàng)建。
又 當(dāng)你訪問靜態(tài)頁面時,根本不會生成servlet,所以也不會創(chuàng)建session。
下面解釋一些疑惑: session是第一次請求時創(chuàng)建的?
大家都知道 jsp是被編譯成servlet才執(zhí)行的,問題就在jsp編譯的過程。
jsp中有個<%@ page session="true/false"%> 這個開關(guān)表示是否創(chuàng)建session,當(dāng)你不寫這行時,它會默認(rèn)給你加上這句。所以會造成上面的疑惑。
當(dāng)然還有一些標(biāo)簽中可能有g(shù)etSession()操作,會產(chǎn)生一些不必要的session。
session只能在服務(wù)端銷毀,有三種途徑: 1,到達session的最大請求間隔時間時,2,session。invalidate()
3,服務(wù)器進程當(dāng)?shù)簟?/p>
這里也有一些疑惑: 瀏覽器關(guān)閉時,session就會注銷。
首先瀏覽器關(guān)閉時,瀏覽器并沒有給服務(wù)器發(fā)送任何消息,所以服務(wù)器不會知道瀏覽器何時關(guān)閉了。
上面我們知道取得session 是因為瀏覽器cookie中有sessionid,而普通cookie通常會是會話cookie,也就是說瀏覽器關(guān)閉時,這個cookie會被注銷,
所以當(dāng)你再訪問服務(wù)器時就沒有sessionid了,所以造成session關(guān)閉了的假象,如果昵稱通過特殊方法將sessionid傳遞給服務(wù)器,你會發(fā)現(xiàn)session還在。
如果想讓cookie保存時間長一些,就需要手動指定cookie的過期時間
4,實際項目中的難點:
1,瀏覽器禁用cookie
這就沒辦法保存sessionid了,可以采用url重寫,轉(zhuǎn)發(fā),加隱藏字段等方法來將sessionid傳給服務(wù)器。
如: baidu.com:jsessionid=adfasdfasdfasdfasdfafdadf?asdfasdf
baidu.com?jsessionid=asdfasdfasdfadsfad&&adfdf
這根據(jù)服務(wù)器的不同實現(xiàn),第一種可以將普通參數(shù)區(qū)分開。
2,多人共用session的問題
例: a 訪問 baidu.com ,但他沒有帳號,于是他將連接 baidu.com/login.jsp?jsessionid=adsfasdfad(這個a的sessionid) 發(fā)給B, B登錄
后,a就相當(dāng)于用b的帳號登錄了。你們可以在在本地試試。
解決方法: 當(dāng)發(fā)現(xiàn)通過sessionid從url指定時, 創(chuàng)建一個新的session,將舊session的信息復(fù)制到 新sessoin中,然后將新session注銷。
就能防止上面那種情況了。
3,一個帳號多地方登錄
比如: 你用abc帳號登錄了baidu.com,有打開了一個瀏覽器,又用abc帳號登錄了一次。當(dāng)不設(shè)計敏感操作時,這無所謂,而當(dāng)你做一些敏感操
作時就必須禁止這樣情況,防止同時操作,造成重復(fù)操作,或者數(shù)據(jù)損壞。
解決方法: 監(jiān)聽session,將username和sessionid對應(yīng)起來,當(dāng)username再次登錄時,注銷掉以前的session,保存現(xiàn)在的session,這也是
一種比較不錯的方案。

其他:
2、session何時被刪除
3、如何做到在瀏覽器關(guān)閉時刪除session
4、有個HttpSessionListener是怎么回事
你可以創(chuàng)建這樣的listener去監(jiān)控session的創(chuàng)建和銷毀事件,使得在發(fā)生這樣的事件時你可以做一些相應(yīng)的工作。注意是session的創(chuàng)建和銷毀動作觸發(fā)listener,
而不是相反。類似的與HttpSession有關(guān)的listener還有 HttpSessionBindingListener,HttpSessionActivationListener和 HttpSessionAttributeListener。
5、存放在session中的對象必須是可序列化的嗎
6、如何才能正確的應(yīng)付客戶端禁止cookie的可能性
7、開兩個瀏覽器窗口訪問應(yīng)用程序會使用同一個session還是不同的session
參見第三小節(jié)對cookie的討論,對session來說是只認(rèn)id不認(rèn)人,因此不同的瀏覽器,不同的窗口打開方式以及不同的cookie存儲方式都會對這個問題
的答案有影響。
8、如何防止用戶打開兩個瀏覽器窗口操作導(dǎo)致的session混亂
9、為什么在Weblogic Server中改變session的值后要重新調(diào)用一次session.setValue