在網絡應用中,Session對象存儲特定用戶會話所需的屬性及配置信息,實現會話保持和跟蹤,本文將詳細總結Session相關的知識點。
session概述
HTTP協議是一種無狀態(tài)的協議,用戶通過瀏覽器訪問服務端的每次請求都是相互獨立的,服務端無法直接通過HTTP請求來判斷上次請求的用戶和本次請求的用戶是否是同一人,當然,你可以使用Cookie來傳遞用戶狀態(tài)的標識,但是每次發(fā)起請求都必須來回傳遞這些Cookie數據,為了實現更多的狀態(tài)跟蹤,傳遞的Cookie數據會越來越多,這無形中增加了瀏覽器與服務端的數據傳輸的壓力和復雜性,Cookie的大小不僅有限制,而且這種方式是不安全的,容易被盜取和篡改,然而session的出現正解決了這些問題。session是存儲于服務端的、用于記錄和保持某些狀態(tài)的一種會話跟蹤技術。用戶通過瀏覽器發(fā)起請求的時候,不用每次都回傳所有的Cookie值了,只要回傳一個key-value的鍵值對就可以了,一般情況下這個key為JSESIONID,value為客戶端第一次訪問服務端時生成的唯一值,這個value可以標識和跟蹤用戶的會話信息,這個value在服務端被習慣稱作sessionId。
如何傳遞sessionId
客戶端可以通過以下三種方式將JSESSIONID的key-value鍵值對傳遞到服務端。
1.如果用戶瀏覽器不支持Cookie或Cookie被禁止了,瀏覽器將會把這個key-value鍵值對重寫到請求的URL參數中,重寫的格式如/xxx/path/abcAction;key=value?paramName=paramValue,其中的key-value就是要傳遞的參數。服務端接收到請求后,會從URL中取到這個key對應的value,并將這個value設置到request,具體的代碼是request.setRequestedSessionId。
2.如果瀏覽器支持Cookie,則瀏覽器在發(fā)請求的時候將會在Request Headers中設置key-value的請求參數,服務端接收到請求后,將會取出這個value值,同時這個value值會覆蓋掉從URL中取得的值。
3.基于SSL,默認情況下不支持,只有connector.getAttribute("SSLEnabled")為true時才支持。
如何保持session會話
正常情況下,用戶第一次通過瀏覽器請求服務端的時候是沒有value的,此時服務端會通過request.getSession()方法創(chuàng)建一個HttpSession對象,并給它設置一個有效期,然后將這個對象存儲在sessions的容器中,同時會把sessionId返回給瀏覽器端。如果用戶再次發(fā)起請求,服務端在解析得到sessionId后,會判斷sessionId對應的HttpSession是否存在,如果不存在,會創(chuàng)建一個HttpSession對象,并將這個對象存儲在sessions的容器中,同時會把sessionId返回給瀏覽器端;如果存在,將可以得到對應的HttpSession對象,這個HttpSession對象可以存儲很多狀態(tài)或表示數據,如session.setAttribute(),從而實現會話跟蹤。
session對象都有一個有效期,一般情況下,應用容器都會有一個后臺線程用于檢查每個session是否失效,如果失效將會被清除。而值得注意的是,調用request.getSession()時會檢查對應的session對象是否過期,如果過期將會創(chuàng)建一個新session對象。
在應用容器重啟或關閉的時候,未過期的session對象會被持久化到一個SESSIONS.ser文件中,當應用容器再次啟動的時候,會重新讀取SESSIONS.ser中所有未過期的session對象,并將它們存儲到sessions集合中。一個應用服務器存儲一套session數據。