一。Session簡介javascript
在Web開發環境下,Session和Cookie同樣,也是用來記錄瀏覽器和服務器之間的狀態信息,保持訪問用戶與後端服務器的交互狀態。session是指一類用來在客戶端與服務器端之間保持狀態的解決方案。有時候Session也用來指這種解決方案的存儲結構,好比說把某信息存儲在session中。html
1. session機制java
session機制採用的是在服務器端保持 HTTP 狀態信息的方案 。
服務器使用一種相似於散列表的結構(也可能就是使用散列表)來保存信息。
當程序須要爲某個客戶端的請求建立一個session時,服務器首先檢查這個客戶端的請求裏是否包含了一個session標識(即sessionId),若是已經包含一個sessionId則說明之前已經爲此客戶建立過session,服務器就按照session id把這個session檢索出來使用(若是檢索不到,可能會新建一個,這種狀況可能出如今服務端已經刪除了該用戶對應的session對象,但用戶人爲地在請求的URL後面附加上一個JSESSION的參數)。若是客戶請求不包含sessionId,則爲此客戶建立一個session而且生成一個與此session相關聯的sessionId,這個session id將在本次響應中返回給客戶端保存。 web
總結以下:編程
第一步:
服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識 - 稱爲session id,
此時就是兩種可能,客戶機有session id或者沒有session id後端
第二步:
若是已包含一個session id則說明之前已經爲此客戶端建立過session,服務器就按照session id把這個session檢索出來使用(若是檢索不到,可能會新建一個)
若是客戶端請求不包含session id,則爲此客戶端建立一個session而且生成一個與此session相關聯的session id
(session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。)瀏覽器
二。Cookie與Session區別服務器
具體來講cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在服務器端保持狀態的方案。同時咱們也看到,因爲採用服務器端保持狀態的方案在客戶端也須要保存一個標識,因此session機制可能須要藉助於cookie機制來達到保存標識的目的,但實際上它還有其餘選擇。
1.Cookie保存在客戶端,Session保存在服務器端。2.Session不像Cookie那樣存在路徑問題,同一個application下面的servlet/jsp能夠共享同一個Session對象,前提是客戶端在同一個窗口下(第一個窗口和其子窗口)。一個窗口和其子窗口對應的是同一個session對象,不一樣窗口對應不一樣的session對象。cookie
三。Session的實現方式(即保存session id 的方法)session
兩種方式:
經過Cookie實現,即將sessionid存放在cookie裏面。
若是瀏覽器不支持Cookie, 必須本身編程使用URL重寫的方式實現Session,即把session id直接附加在URL路徑。經過方法response.encodeURL()實現,做用有2:1.轉碼 2.URL後面加入SessionId
還有一種技術叫作表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時可以把session id傳遞迴服務器。好比: <form name="testform" action="/xxx"> <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"> <input type="text"> </form>
四。Session的建立與刪除
一個常見的錯誤是覺得session在有客戶端訪問時就被建立,然而事實是直到某server端程序(如Servlet)調用HttpServletRequest.getSession(true)這樣的語句時纔會被建立。
session在下列狀況下被刪除:
A.程序調用HttpSession.invalidate()
B.距離上一次收到客戶端發送的session id時間間隔超過了session的最大有效時間
C.服務器進程被中止
注意:關閉瀏覽器只會使存儲在客戶端瀏覽器內存中的session cookie失效,不會使服務器端的session對象失效。
五。兩個瀏覽器窗口訪問應用程序會使用同一個session
一般session cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的session id,這樣信息共享的目的就達不到了。
此時能夠先把session id保存在persistent cookie中(經過設置cookie的最大有效時間),而後在新窗口中讀出來,就能夠獲得上一個窗口的session id了,這樣經過session cookie和persistent cookie的結合就能夠實現了跨窗口的會話跟蹤。
六。Session的超時管理
WEB服務器沒法判斷當前的客戶端瀏覽器是否還會繼續訪問,也沒法檢測客戶端瀏覽器是否關閉,因此,即便客戶已經離開或關閉了瀏覽器,WEB服務器還要保留與之對應的HttpSession對象。
隨着時間的推移而不斷增長新的訪問客戶端,WEB服務器內存中將會所以積累起大量的再也不被使用的HttpSession對象,並將最終致使服務器內存耗盡。
WEB服務器採用「超時限制」的辦法來判斷客戶端是否還在繼續訪問,若是某個客戶端在必定的時間以內沒有發出後續請求,WEB服務器則認爲客戶端已經中止了活動,結束與該客戶端的會話並將與之對應的HttpSession對象變成垃圾。
若是客戶端瀏覽器超時後再次發出訪問請求,WEB服務器則認爲這是一個新的會話的開始,將爲之建立新的HttpSession對象和分配新的會話標識號。
會話的超時間隔能夠在web.xml文件中設置,其默認值由Servlet容器定義。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
Session cookie
session經過SessionID來區分不一樣的客戶, session是以cookie或URL重寫爲基礎的,默認使用cookie來實現,系統會創造一個名爲JSESSIONID的輸出cookie,這稱之爲session cookie,以區別persistent cookies(也就是咱們一般所說的cookie),session cookie是存儲於瀏覽器內存中的,並非寫到硬盤上的,一般看不到JSESSIONID,可是當把瀏覽器的cookie禁止後,web服務器會採用URL重寫的方式傳遞Sessionid,這時地址欄看到session cookie針對某一次會話而言,會話結束session cookie也就隨着消失了,而persistent cookie只是存在於客戶端硬盤上的一段文本。
關閉瀏覽器,只會是瀏覽器端內存裏的session cookie消失,但不會使保存在服務器端的session對象消失,一樣也不會使已經保存到硬盤上的持久化cookie消失。
七。session中的一些問題
(1)、session在什麼時候被建立
一個常見的誤解是覺得session在有客戶端訪問時就被建立,然而事實是直到某server端程序調用 HttpServletRequest.getSession(true)這樣的語句時才被建立,注意若是JSP沒有顯示的使用 <%@pagesession="false"%> 關閉session,則JSP文件在編譯成Servlet時將會自動加上這樣一條語句HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的session對象的來歷。
因爲session會消耗內存資源,所以,若是不打算使用session,應該在全部的JSP中關閉它。
(2)、session什麼時候被刪除
綜合前面的討論,session在下列狀況下被刪除a.程序調用HttpSession.invalidate();或b.距離上一次收到客戶端發送的session id時間間隔超過了session的超時設置;或c.服務器進程被中止(非持久session)
(3)、如何作到在瀏覽器關閉時刪除session
嚴格的講,作不到這一點。能夠作一點努力的辦法是在全部的客戶端頁面裏使用網頁特效代碼window.onclose來監視瀏覽器的關閉 動做,而後向服務器發送一個請求來刪
除session。可是對於瀏覽器崩潰或者強行殺死進程這些很是規手段仍然無能爲力。
(4)、有個HttpSessionListener是怎麼回事
你能夠建立這樣的listener去監控session的建立和銷燬事件,使得在發生這樣的事件時你能夠作一些相應的工做。注意是 session的建立和銷燬動做觸發listener,而不是相反。相似的與HttpSession有關的listener還有 HttpSessionBindingListener,HttpSessionActivationListener和 HttpSessionAttributeListener。
(5)、存放在session中的對象必須是可序列化的嗎
不是必需的。要求對象可序列化只是爲了session可以在集羣中被複制或者可以持久保存或者在必要時server可以暫時把session交換出內 存。在Weblogic Server的session中放置一個不可序列化的對象在控制檯上會收到一個警告。我所用過的某個iPlanet版本若是session中有不可序列化 的對象,在session銷燬時會有一個Exception,很奇怪。
(6.)、如何才能正確的應付客戶端禁止cookie的可能性
對全部的URL使用URL重寫,包括超連接,form的action,和重定向的URL,具體作法參見[6]http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770
(7.)、開兩個瀏覽器窗口訪問應用程序會使用同一個session仍是不一樣的session
參見第三小節對cookie的討論,對session來講是隻認id不認人,所以不一樣的瀏覽器,不一樣的窗口打開方式以及不一樣的cookie存儲方式都會對這個問題的答案有影響。
(8.)、如何防止用戶打開兩個瀏覽器窗口操做致使的session混亂
這個問題與防止表單屢次提交是相似的,能夠經過設置客戶端的令牌來解決。就是在服務器每次生成一個不一樣的id返回給客戶端,同時保存在 session裏,客戶端提交表單時必須把這個id也返回服務器,程序首先比較返回的id與保存在session裏的值是否一致,若是不一致則說明本次操 做已經被提交過了。能夠參看《J2EE核心模式》關於表示層模式的部分。須要注意的是對於使用javascript window.open打開的窗口,通常不設置這個id,或者使用單獨的id,以防主窗口沒法操做,建議不要再window.open打開的窗口裏作修改 操做,這樣就能夠不用設置。
(9.)、爲何在Weblogic Server中改變session的值後要從新調用一次session.setValue作這個動做主要是爲了在集羣環境中提示Weblogic Server session中的值發生了改變,須要向其餘服務器進程複製新的session值。
(10)、爲何session不見了
排除session正常失效的因素以外,服務器自己的可能性應該是微乎其微的,雖然筆者在iPlanet6SP1加若干補丁的Solaris版本上倒 也遇到過;瀏覽器插件的可能性次之,筆者也遇到過3721插件形成的問題;理論上防火牆或者代理服務器在cookie處理上也有可能會出現問題。
出現這一問題的大部分緣由都是程序的錯誤,最多見的就是在一個應用程序中去訪問另一個應用程序
聲明:文章部分轉載:http://blog.163.com/wf_shunqiziran/blog/static/176307209201257112256234/
http://www.cnblogs.com/cobbliu/archive/2012/03/10/2388568.html
僅爲學習之用。