本篇文章簡單記錄了關于Web會話管理技術的學習筆記。
目前常用的會話管理技術是Cookie與Session
- Cookie通過在客戶端記錄信息確定用戶身份
- Session通過在服務器端記錄信息確定用戶身份。
會話管理
- 會話管理: 管理瀏覽器和服務器之間的會話過程中產生的會話數據
Cookie
Cookie機制的引入
在Web應用程序是使用HTTP協議傳輸數據的。HTTP協議是無狀態的協議。一旦數據交換完畢,客戶端與服務器端的連接就會關閉,再次交換數據需要建立新的連接。這就意味著服務器無法從連接上跟蹤會話。
Cookie就是記錄會話數據這樣的一種機制。它可以彌補HTTP協議無狀態的不足。
Cookie原理
Cookie是客戶端技術,服務器把每個用戶的數據以cookie的形式寫給用戶各自的瀏覽器。當用戶使用瀏覽器再去訪問服務器中的web資源時,就會帶著各自的數據去,這樣,web資源處理的就是用戶各自的數據了。
Cookie機制的流程
- 服務器創建cookie對象,把會話數據存儲到cookie對象中。
new Cookie("name","value"); - 服務器發送cookie信息到瀏覽器
response.addCookie(cookie);
舉例: set-cookie: name=xiseven (隱藏發送了一個set-cookie名稱的響應頭) - 瀏覽器得到服務器發送的cookie,然后保存在瀏覽器端。
- 瀏覽器在下次訪問服務器時,會帶著cookie信息
舉例: cookie: name=xiseven (隱藏帶著一個叫cookie名稱的請求頭) - 服務器接收到瀏覽器帶來的cookie信息
request.getCookies();
Cookie核心API
1)構造Cookie對象
Cookie(java.lang.String name, java.lang.String value)
2)設置cookie
//設置cookie的有效訪問路徑
void setPath(java.lang.String uri)
//設置cookie的有效時間
void setMaxAge(int expiry)
//設置cookie的值
void setValue(java.lang.String newValue)
//設置cookie的有效域
void setDomain(String pattern)
3)發送cookie到瀏覽器端保存
//發送cookie
void response.addCookie(Cookie cookie)
4)服務器接收cookie
//接收cookie
Cookie[] request.getCookies()
Cookie細節
一個Cookie只能標識一種信息,它至少含有一個標識該信息的名稱(NAME)和設置值(VALUE)。
void setPath(java.lang.String uri) :設置cookie的有效訪問路徑。有效路徑指的是cookie的有效路徑保存在哪里,那么瀏覽器在有效路徑下訪問服務器時就會帶著cookie信息,否則不帶cookie信息。
void setMaxAge(int expiry) : 設置cookie的有效時間。
正整數:表示cookie數據保存瀏覽器的緩存目錄(硬盤中),數值表示保存的時間。
負整數:表示cookie數據保存瀏覽器的內存中。瀏覽器關閉cookie就丟失了!!
零:表示刪除同名的cookie數據
注意,刪除cookie時,path必須一致,否則不會刪除一個WEB站點可以給一個WEB瀏覽器發送多個Cookie,一個WEB瀏覽器也可以存儲多個WEB站點提供的Cookie,但是瀏覽器一般只允許存放300個Cookie,每個站點最多存放20個Cookie,每個Cookie的大小限制為4KB。
Cookie中存儲中文
//必須使用URLEncoder類里面的encode(String s, String enc)方法進行中文轉碼
Cookie cookie = new Cookie("userName", URLEncoder.encode("用戶名", "UTF-8"));
response.addCookie(cookie);
//獲取cookie中的中文數據,使用URLDecoder類里面的decode(String s, String enc)進行解碼
URLDecoder.decode(cookies[i].getValue(), "UTF-8");
Session
Session機制的引入
- Cookie的局限:
- Cookie只能存字符串類型。不能保存對象
- 不能直接存儲中文字符。
- 1個Cookie的容量不超過4KB。
因為Cookie的種種局限所以引入Session機制,可以很好的解決以上的問題
Session原理
Session是服務器技術,服務器可以為每個用戶瀏覽器創建一個會話對象(session對象),注意:一個瀏覽器獨占一個session對象(默認情況下)。因此,在需要保存用戶數據時,服務器程序可以把用戶數據寫到用戶瀏覽器獨占的session中,當用戶使用瀏覽器訪問其它程序時,其它程序可以從用戶的session中取出該用戶的數據,為用戶服務。
Session機制的流程:
以下是服務器內部的行為
- 第一次訪問創建session對象,給session對象分配一個唯一的ID,叫JSESSIONID
new HttpSession(); - 把JSESSIONID作為Cookie的值發送給瀏覽器保存
Cookie cookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie); - 第二次訪問的時候,瀏覽器帶著JSESSIONID的cookie訪問服務器
- 服務器得到JSESSIONID,在服務器的內存中搜索是否存放對應編號的session對象。
服務器搜索session對象的偽代碼
if(找到){
return map.get(sessionID);
}
存儲session對象的Map結構
Map<String,HttpSession>
<"001", s1>
<"001", s2>
- 如果找到對應編號的session對象,直接返回該對象
- 如果找不到對應編號的session對象,創建新的session對象,繼續走1的流程
Session核心API
方法 | 描述 |
---|---|
void setAttribute(String attribute, Object value) | 設置Session屬性。value參數可以為任何Java Object。通常為Java Bean。value信息不宜過大 |
String getAttribute(String attribute) | 返回Session屬性 |
Enumeration getAttributeNames() | 返回Session中存在的屬性名 |
void removeAttribute(String attribute) | 移除Session屬性 |
String getId() | 返回Session的ID。該ID由服務器自動創建,不會重復 |
long getCreationTime() | 返回Session的創建日期。返回類型為long,常被轉化為Date類型,例如:Date createTime = new Date(session.getCreationTime()) |
long getLastAccessedTime() | 返回Session的最后活躍時間。返回類型為long |
int getMaxInactiveInterval() | 返回Session的超時時間。單位為秒。超過該時間沒有訪問,服務器認為該Session失效 |
void setMaxInactiveInterval(int second) | 設置Session的超時時間。單位為秒 |
boolean isNew() | 返回該Session是否是新創建的 |
void invalidate() | 使該Session失效 |
Session細節
-
兩個getSession方法:
- getSession(true) / getSession() : 創建或得到session對象。沒有匹配的session編號,自動創建新的session對象。
- getSession(false) : 得到session對象。沒有匹配的session編號,返回null
-
Session對象銷毀時間:
- 手動銷毀Session對象invalidate()
- 默認情況30分鐘不訪問服務器自動回收
- 手動修改Session回事時間setMaxInactiveInterval()
- 全局修改Session有效時間(修改web.xml)
<!-- 修改session全局有效時間:分鐘 --> <session-config> <session-timeout>1</session-timeout> </session-config>
-
瀏覽器禁用Cookie后的Session處理
解決方案:URL重寫,使用一下方法可將SessionId信息寫入URL,不必依賴于Cookie- response. encodeRedirectURL(java.lang.String url)
用于對sendRedirect方法后的url地址進行重寫。 - response. encodeURL(java.lang.String url)
用于對表單action和超鏈接的url地址進行重寫
- response. encodeRedirectURL(java.lang.String url)