概述
- 問題引入
- HTTP協定是一種無狀态的協定。WEB伺服器本身不能識别出哪些請求是同一個浏覽器發出的且每次請求是完全孤立的
- HTTP1.1支援持續連接配接,但當使用者有一段時間沒提出請求,連接配接也會關閉
- 是以作為WEB伺服器,必須能夠采用一種機制來唯一地識别一個使用者,同時記錄該使用者的狀态
- 會話
- 浏覽器與伺服器之間連續發生的一系列請求與響應過程
- 會話狀态
- 浏覽器與伺服器之間在會話過程中産生的狀态資訊,借助會話狀态,可把一系列請求與響應過程關聯起來
- 會話ID
- WEB伺服器能識别出同一個浏覽器的通路請求,需浏覽器對其發出每個請求都進行識别,屬于同一個會話的請求帶同樣的辨別号,辨別号稱之為會話ID
- 完成會話跟蹤機制:Cookie,Session
Cookie
- 在浏覽器通路WEB伺服器的某個資源時,由WEB伺服器在HTTP響應資訊頭中附帶傳送給浏覽器的一個小文本檔案(Cookie)
- 一旦浏覽器儲存了某個Cookie,以後每次通路WEB伺服器時都在HTTP請求頭中将Cookie回傳給WEB伺服器
- 一個Cookie隻能識别一種資訊,至少包含一個識别該資訊的名稱和設定值
- WEB伺服器可給浏覽器發送多個Cookie,浏覽器也可接受多個伺服器提供的Cookie
- 浏覽器一般隻允許存放300個Cookie,web站點最多存放20個Cookie,每個Cookie大小限制為4KB
方法
- Servlet API中提供一個Cookie類來封裝Cookie資訊,包含生成和提起Cookie資訊各個屬性的方法
- public Cookie(String name,String value) //建立
- String geyName() //擷取Cookie的名稱
- String getValue() //擷取Cookie的值
- int getMaxAge() //擷取cookie的過期時間,以秒為機關
- String getPath(String uri) //擷取Cookie的使用路徑
- String getDomain() //擷取Cookie适用的域
- void setValue(String value) //在Cookie建立後,為Cookie賦予新的值
- void setMaxAge(int expiry) //設定Cookie的過期時間,以秒為機關
- void setPath(String uri) //設定Cookie的使用路徑
- void setDomain(String pattern) //設定通路Cookie的域名
- HttpServletResponse接口
- response.addCookie(Cookie cookie) //将一個Cookie對象傳入用戶端,将Cookie插入到一個Set-Cookie HTTP響應頭中,而非修改響應頭
- HttpServletRequest接口
- Cookie[] cookies = request.getCookies() //讀取所有Cookie項
- 支援中文
- URLEncoder.encode(資料,“utf-8”) //對資料編碼
- URLDecoder.decode(資料,“utf-8”) //對資料解碼
會話Cookie
- 不設定過期時間,則Cookie的聲明周期為浏覽器會話期間,關閉浏覽器則Cookie消失,會話Cookie一般不儲存在硬碟上而儲存在記憶體中
持久Cookie
- 設定過期時間,浏覽器則把Cookie儲存在硬碟上,關閉浏覽器Cookie不消失,可在不同浏覽器程序間共享,比如兩個IE視窗,而儲存在記憶體中的Cookie,不同浏覽器處理方式不同
Session
- 相比于Cookie,Session是伺服器端使用的一種記錄用戶端狀态的機制,Cookie儲存在用戶端浏覽器中,而Session儲存在伺服器上
- 在web開發過程中,伺服器給每個使用者浏覽器會建立一個會話對象(session對象),一個浏覽器獨享一個session對象,是以在儲存使用者資料時,伺服器程式可以把使用者資料寫到使用者浏覽器獨享的session中。當使用者使用浏覽器通路其他程式時,其他程式可以從使用者的session中取出該使用者的資料,直接使用
- session的實作是依賴于cookie的。伺服器建立Session之後,會把session的ID,以cookie的形式回寫給用戶端(一個cookie中儲存了sessionId),name屬性為JSESSIONID,而資料是儲存在session中,隻要不關閉用戶端,包含sessionId的cookie會一直儲存到浏覽器中,即這次會話中的所有通路該伺服器的請求頭中都會帶上sessionId,而伺服器會通過sessionId找到對應的session,而無需再建立新的session
方法
- HttpSession接口
- void setAttribute(String name, Object value) //設定session中的資料,若多次調用該方法且使用相同的name,那麼會覆寫上一次的值
- Object getAttribute(String name) //擷取session中的資料
- void removeAttribute(String name) //移除session中的資料
- invalidate() //銷毀session,session預設失效時間:30分鐘,伺服器關閉,session銷毀(Cookie銷毀)
- setMaxInactiveInterval(s) //設定session失效時間,s以秒為機關
- getMaxInactiveInterval() //擷取session失效時間
- 在web.xml中設定session失效時間
- <session-config>
- <session-timeout>失效時間</session-timeout>
- </session-config>
- <session-config>
- HttpServletRequest接口
- getSession()或getSession(true) //擷取與建立session對象
- getSession(false) //禁用session
URL位址重寫
- URL位址重寫是對用戶端不支援Cookie的解決方案,URL位址重寫的原理是将該使用者Session的id資訊重寫到URL位址中,伺服器能夠解析重寫後的URL擷取Session的id, HttpServletResponse類提供了encodeURL(String url)實作URL位址重寫
- encodeURL方法會自動判斷用戶端是否支援Cookie。如果用戶端支援Cookie,會将URL原封不動地輸出來。如果用戶端不支援Cookie,則會将使用者Session的id重寫到URL中
- response.encodeRedirectURL(String url) 用于對sendRedirect方法後的url位址進行重寫
差別
- Cookie儲存在用戶端,未設定存儲時間的Cookie,關閉浏覽器會話Cookie就會被删除;設定了存儲時間的Cookie儲存在使用者裝置的磁盤中直到過期,同時Cookie在用戶端可以僞造,不是十分安全,敏感資料不易儲存。Session儲存在伺服器端,存儲在IIS的程序開辟的記憶體中,而Session過多會消耗伺服器資源,是以盡量少使用Session
- Session技術把使用者的資料寫到使用者獨占的session中,通過SessionID使用者能夠與伺服器端成千上萬的Session進行比對,同時也保證了不同頁面之間傳值的正确性
- 存儲資料類型不同:Session能夠存儲任意的Java對象,Cookie隻能存儲String類型的對象
- 大于10K的資料,不能使用Cookies