Servlet編程專題7之HttpSession
- Session,即會話,是Web開發中的一種會話狀態跟蹤技術。當然,前面所講述的Cookie也是一種會話跟蹤技術。不同的是Cookie是將會話狀態保存在了客戶端,而Session則是將會話狀態保存到了服務器端。
- 那麽,到底什麽是“會話”?當用戶打開瀏覽器,從發出第一次請求開始,一直到最終關閉瀏覽器,就表示一次會話的完成。
- Session並不是JavaWeb開發所持有的,而是整個Web開發中所使用的技術。在JavaWeb開發中,Session是以javax.servlet.http.HttpSession的接口對象的形式出現的。
1、Session的訪問:
a、Session對象的創建:
javax.servlet.http.HttpServletRequest接口中有兩個方法,getSession()方法和getSession(boolean create)方法:
- getSession()方法:用於返回與請求相關聯的當前session,或者如果請求中沒有session,創建一個並返回。
- getSession()方法:用於返回與請求相關聯的當前session,或者傳入的參數為true時,如果請求中沒有session,創建一個並返回。(如果傳入的參數為false時,不創建Session,返回null。)
2、對Session域屬性空間的操作:
- Session是一個專門用於存放數據的集合,我們一般稱這個用於存放數據的內存空間為域屬性空間,簡稱為域。HttpSession中具有三個方法,是專門用於對該域屬性空間中數據進行寫、讀操作的。
3、Session的工作原理:在服務器中系統會為每個會話維護一個Session。不同的會話,對應不同的Session。那麽,系統是如何識別各個Session對象的?即是如何做到在同一個會話過程中,一直使用的是同一個Session對象的?
a、寫入Session列表:
- 服務器對當前應用中的Session是以Map的形式進行管理的,這個Map稱之為Session列表。該Map的key為一個32位長度的隨機串,這個隨機串稱之為JSessionID,value則為Session對象的引用。
- 當用戶第一次提交請求時,服務器Servlet中執行到request.getSession()方法後,會自動生成一個Map.Entry對象,key為一個根據某種算法新生成的JSessionID,value則為新創建的HttpSession對象。
b、服務器生成並發送Cookie:
- 在將Session信息寫入Session列表之後,系統還會自動將“JSESSIONID”作為name,這個32位長度的隨機串作為value,以Cookie的形式存放到響應報頭中,並隨著響應,將該Cookie發送到客戶端中。
c、客戶端接收並發送Cookie:
- 客戶端接收這個Cookie後會將其存放到瀏覽器的緩存中。即,只要客戶端瀏覽器不關閉,瀏覽器緩存中的Cookie就不會失效。
- 當用戶提交第二次請求時,會將緩存中的這個Cookie,伴隨著請求的頭部信息,一塊發送給服務器
d、從Session列表中查找:
- 服務器從請求中讀取到客戶端發送來的Cookie,並根據Cookie的JSSESSIONID的值,從Map中查找相應key對應的value,即Session對象。然後,對該Session對象的域屬性進行讀寫操作。
4、Session的失效:
- Web開發中引入的Session超時的概念,Session的失效就是指Session的超時。若某個Session在指定的時間範圍內一直未被訪問,那麽Session將超時,即將失效。
- 在web.xml中可以通過<session-config>標簽設置Session的超時時間,單位為分鐘。默認Session的超時時間為30分鐘。需要再次強調的是,這個時間並不是從Session被創建開始計時的生命周期長,而是從最後一次被訪問開始計時,在指定的時長內一直未被訪問的時長。
- 若未到超時時限,也可以通過代碼提前使Session失效。使用
javax.servlet.http.HttpSession接口中的invalidate()方法:5、Cookie禁用後使用Session進行會話跟蹤:
- 從前面Session的工作原理可知,服務器之所以可以針對不同的會話找到不同的Session,是因為Cookie完成了會話的跟蹤。但是,若客戶端瀏覽器將Cookie禁用,那麽服務器還怎麽保證同一會話使用的是同一個Session呢?
- 若客戶端瀏覽器禁用了Cookie,會發現向服務器所提交的每一次請求,服務器在給出的響應中都會包含名稱為JSESSIONID的Cookie,只不過這個Cookie的值每一次都不同。也就是說,只要客戶端瀏覽器所提交的請求中沒有包含JSESSIONID,服務器就會認為這是一個新的會話的開始,就會為其生成一個Map.Entry對象,key為新的32位長度的隨機串,value為新創建的Session會話引用。這樣的話,也就無法實現會話跟蹤。
- 附加說明:
a、域屬性空間範圍對比:
- 在JavaWeb編程的API中,存在四個可以存放域屬性的空間範圍對象,這四個對象中所存儲的域屬性作用範圍,由大到小分別為:
- ServletContext -> HttpSession -> HttpServletRequest -> PageContext
- ServletContext,即application,置入其中的域屬性是整個應用範圍的,可以完成跨會話共享數據。
- HttpSession,置入其中的域屬性是會話範圍的,可以完成跨請求共享數據。
- HttpServletRequest,置入其中的域屬性是請求範圍的,可以完成跨Servlet共享數據,但是這些Servlet必須在同一個請求中。
- PageContext,置入其中的域屬性是頁面範圍的,不常用。
- 對於ServletContext,HttpSession,HttpServletRequest這三個域屬性空間對象的使用原則是,在可以保證功能需求的前提下,優先使用小範圍的。這樣不僅可以節省服務器內存,還可以保證數據的安全性。
本文出自 “12392717” 博客,請務必保留此出處http://12402717.blog.51cto.com/12392717/1976574
Servlet編程專題7之HttpSession