13,使用Cookie
Cookie是在瀏覽器存儲信息的一種方式,服務器可以響應瀏覽器set-cookie標頭,瀏覽器收到這個標頭與數值後,會將它以文件的形式存儲
在計算機上,這個文件就稱之爲Cookie。
HTTP中Cookie的設定是通過set-cookie標頭,所以必須在實際響應瀏覽器之前使用addCookie()來新增Cookie實例,在瀏覽器輸出HTML響應之後
再運行addCookie()是沒有作用的。
取得瀏覽器存儲Cookie,可以從HttpServletRequest的getCookies()來取得,這可取得該網頁所屬域的所有Cookie,所以返回值是Cookie[]數組:
Cookie[] cookies=request.getCookies();
if(cookies!=null){
for(Cookies cookie:cookies){
String name=cookie.getName();
String value=cookie.getValue();
................
}
}
14,HttpSession會話管理原理
HttpSession並非線程安全,所以必須注意屬性設定時共享存取的問題。
實際上如何得知數個請求間的關係是由Web容器執行的,Web應用程序基於HTTP協議無狀態的事實並沒有改變。
嘗試運行HttpServletRequest的getSession()時,Web容器會創建HttpSession對象,關鍵在於每個HttpSession對象都會有個特殊的ID
,稱爲SessionID。SessionID默認會使用Cookie存放在瀏覽器中,在Tomcat中,Cookie的名稱時JSESSIONID,數值則是getID取得的
SessionID。
由於Web容器本身是執行於JVM中的一個java程序,通過getSession()取得HttpSession,是Web容器中的一個java對象,HttpSession中存放的屬性,自然
也存在於服務端web容器中。每一個HttpSession各有特殊的SessionID,當瀏覽器請求應用程序時,會將Cookie中存放的SessionID一併發送給應用程序,
Web容器會根據SessionID來找出對應的HttpSession對象,這樣可以取得各瀏覽器個別的會話數據。
所以使用HttpSession進行繪畫管理,設定爲屬性的對象存儲與服務端,SessionID默認使用Cookie存放於瀏覽器端。Web容器存儲SessionID的Cookie默認爲
關閉瀏覽器就失效,所以重新啓動瀏覽器請求應用程序時,通過getsession取得的是新的HttpSession對象。
默認關閉瀏覽器會馬上失效的是瀏覽器上的Cookie,不是HttpSession。因爲Cookie失效了,就無法通過Cookie來發送SessionID,所以嘗試getSession(),容器會產生
新的HttpSession。要讓HttpSession立即失效必須調用invalidate()方法,否則HttpSession會等到設定的時間過後纔會被容器銷燬回收。
15,HttpSession與URL重寫
HttpSession默認使用Cookie存儲SessionID,如果用戶關掉瀏覽器接收Cookie的功能,就無法使用Cookie在瀏覽器存儲SessionID。如果在
用戶禁掉Cookie的情況下,仍打算運用HttpSession來進行會話管理,那麼可以搭配URL重寫。
使用URL重寫的方式來發送SessionID,可以使用HttpServletResponse的encodeURL()協助產生所需的URL重寫。
若能從HTTP請求中取得帶有SessionID的Cookie,encodeURL()會將傳入的URL原封不動地輸出。如果容器嘗試取得HttpSession實例時,無法從HTTP請求中取得帶有
SessionID的Cookie時(通常爲瀏覽器禁用Cookie的情況),encodeURL()會自動產生帶有SessionID的URL重寫。
如果執行encodeURL(),在瀏覽器第一次請求網站時,容器並不知道瀏覽器是否禁用Cookie,所以容器的作法是Cookie(發送set-cookie標頭)與URL重寫
的方式,因此若Servlet有以下語句,無論瀏覽器有無禁用Cookie,第一次請求時,都會現實在SessionID的URL:
request.getSession();
out.println(response.encodeURL("index.jsp"));
有一個encodeRedirectURL()方法,則可以在要求瀏覽器重定向時,在URL上顯示SessionID。