瀏覽器與服務器之間的會話管理(Cookie/Session技術)
1、什么是會話:
用戶打開瀏覽器,點擊多個超鏈接,訪問服務器的多個web資源,然后關閉瀏覽器,整個過程就稱為一個會話;
2、會話過程需要解決的問題:
每個用戶在使用瀏覽器與服務器進行會話的過程中,都可能會產生一些數據,這些輸入如何來進行保存?比如用戶在購物網站瀏覽的商品記錄,用戶添加購物車的記錄等等這些信息如何進行存儲?在程序中會話跟蹤是一件非常重要的事情,一個用戶的所有請求操作都應該屬於同一個會話,而另一個人的所有請求操作應該屬於另一個人,二者不能混淆!當想到需要在保存數據時,我們首先肯定會想到使用域對象,這些數據是否可以使用Request或者ServletContext對象來保存呢?
首先我們舉例說明:登錄的場景
2.1 、Context對象:
小張: 輸入“張三” (保存數據: context.setAttribute("name","張三")) -> 用戶主頁(顯示“張三”)
小李: 輸入“李四”(保存數據:context.setAttribute("name","李四")) -> 用戶主頁(顯示“李四”)
context是所有用戶公有的資源,因此當小李登錄后,用戶主頁將全部顯示為“李四”,新的數據將會覆蓋原有的數據,因此不能夠使用context對象;
2.2 、Request對象:
該對象只在同一個頁面有效,當需要進行頁面跳轉的時候,顯然必須使用轉發技術來實現,因此Request對象也不能夠有效解決該問題。
3、會話技術
為了解決上述的問題,這里引入了會話技術,其中會話技術主要分為兩個部分,cookie 技術和 session 技術,前者將數據保存在客戶端,后者將數據保存在服務器。
- Cookie技術:Cookie是客戶端技術,服務器把每個用戶的數據以 cookie 的形式寫給用戶各自的瀏覽器。當用戶使用瀏覽器再去訪問服務器中的web資源時,就會帶着各自的數據去。這樣,web資源處理的就是用戶各自的數據了。
- Session技術:Session是服務器端技術,利用這個技術,服務器在運行時可以為每一個用戶的瀏覽器創建一個其獨享的session對象,由於session為用戶瀏覽器獨享,所以用戶在訪問服務器的web資源時,可以把各自的數據放在各自的session中,當用戶再去訪問服務器中的其它web資源時,其它web資源再從用戶各自的session中取出數據為用戶服務。
(一) Cookie技術
1.1 Cookie技術核心
Cookie類:用於存儲會話數據
1)構造Cookie對象
- new Cookie(String name, String value)
2)設置cookie
- void setPath(String uri) : 設置cookie的有效訪問路徑
- void setMaxAge(int expiry) : 設置cookie的有效時間
- void setValue(String newValue) : 設置cookie的值
3)發送cookie到瀏覽器端保存
- void response.addCookie(Cookie cookie) ;
4)服務器接收cookie, 返回所有cookie的數據信息
- Cookie[] request.getCookies();
1.2 Cookie原理
1)服務器創建cookie對象,把會話數據存儲到cookie對象中。
- new Cookie("name", "value");
2)服務器發送cookie信息到瀏覽器
- response.addCookie(cookie);
舉例: set-cookie: name=Infaraway ( 隱藏發送了一個set-cookie名稱的響應頭 )
3)瀏覽器得到服務器發送的cookie,然后保存在瀏覽器端。
4)瀏覽器在下次訪問服務器時,會帶着cookie信息
舉例: cookie: name=Infaraway (隱藏帶着一個叫cookie名稱的請求頭)
5)服務器接收到瀏覽器帶來的cookie信息
- request.getCookies();
import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CreateCookie { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.創建Cookie對象
Cookie cookie = new Cookie("name", "value"); Cookie cookie2 = new Cookie("yourCookie","id"); /** * 設置cookie的有效路徑。默認情況:有效路徑在當前web應用下。 /cookie */ cookie1.setPath("/cookie"); /** * 設置cookie的有效時間 * 正整數:表示cookie數據保存瀏覽器的緩存目錄(硬盤中),數值表示保存的時間。 * 負整數:表示cookie數據保存瀏覽器的內存中。瀏覽器關閉cookie就丟失了! * 零:表示刪除同名的cookie數據 */ cookie1.setMaxAge(20); //20秒,從最后不調用cookie開始計算
cookie1.setMaxAge(-1); //cookie保存在瀏覽器內存(會話cookie)
cookie1.setMaxAge(0); // 把cookie數據發送到瀏覽器(通過響應頭發送: set-cookie名稱)
response.setHeader("set-cookie", cookie.getName()); //推薦使用這種方法,避免手動發送cookie信息
response.addCookie(cookie1); // 接收瀏覽器發送的cookie信息
String name = request.getHeader("cookie"); System.out.println(name); // 獲取所有的Cookie
Cookie[] cookies = request.getCookies(); //注意:判斷null,否則空指針
if(cookies!=null){ //遍歷
for(Cookie c:cookies){ String name = c.getName(); String value = c.getValue(); System.out.println(name+"="+value); } }else{ System.out.println("沒有接收cookie數據"); } } }
1.3 Cookie的細節
1)void setPath(String uri) :設置cookie的有效訪問路徑。有效路徑指的是cookie的有效路徑保存在哪里,那么瀏覽器在有效路徑下訪問服務器時就會帶着cookie信息,否則不帶cookie信息。
2)void setMaxAge(int expiry) : 設置cookie的有效時間。
- 正整數:表示cookie數據保存瀏覽器的緩存目錄(硬盤中),數值表示保存的時間。
- 負整數:表示cookie數據保存瀏覽器的內存中。瀏覽器關閉cookie就丟失了!!
- 零:表示刪除同名的cookie數據
3)Cookie 數據類型只能保存非中文字符串類型的。可以保存多個cookie,但是瀏覽器一般只允許存放 300 個Cookie,每個站點最多存放20個Cookie,每個Cookie的大小限制為4KB。
(二) Session技術
2.1 引入
Cookie的局限:
- 1)Cookie只能存字符串類型。不能保存對象
- 2)只能存非中文。
- 3)1個Cookie的容量不超過4KB。
如果要保存非字符串,超過4kb內容,只能使用session技術!
Session特點:會話數據保存在服務器端。(內存中)
2.2 Session技術核心
HttpSession類:用於保存會話數據
1)創建或得到session對象
- HttpSession getSession()
- HttpSession getSession(boolean create)
2)設置session對象
- void setMaxInactiveInterval(int interval) : 設置session的有效時間
- void invalidate() : 銷毀session對象
- java.lang.String getId() : 得到session編號
3)保存會話數據到session對象
- void setAttribute(String name, Object value) : 保存數據
- Object getAttribute(String name) : 獲取數據
- void removeAttribute(String name) : 清除數據
2.3 Session原理
問題: 服務器能夠識別不同的瀏覽者!
關鍵: 在哪個session域對象保存數據,就必須從哪個域對象取出!
代碼解讀:HttpSession session = request.getSession();
1)第一次訪問創建session對象,給session對象分配一個唯一的ID,叫JSESSIONID
new HttpSession();
2)把 JSESSIONID 作為Cookie的值發送給瀏覽器保存
Cookie cookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie);
3)第二次訪問的時候,瀏覽器帶着JSESSIONID的cookie訪問服務器
4)服務器得到JSESSIONID,在服務器的內存中搜索是否存放對應編號的session對象。
if(找到){
return map.get(sessionID);
}
5)如果找到對應編號的session對象,直接返回該對象
6)如果找不到對應編號的session對象,創建新的session對象,繼續走1的流程
結論:通過 JSESSION 的 cookie 值在服務器找session對象!
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class CreateSession extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.創建session對象
HttpSession session = request.getSession(); //得到session編號
System.out.println("id=" + session.getId()); //修改session的有效時間
session.setMaxInactiveInterval(20); //手動發送一個硬盤保存的cookie給瀏覽器
Cookie c = new Cookie("JSESSIONID", session.getId()); c.setMaxAge(60*60); response.addCookie(c); //2.保存會話數據
session.setAttribute("name", "Infaraway"); } }
刪除Cookie
import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class DeleteCookie extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * 需求: 刪除cookie */ Cookie cookie = new Cookie("name","xxxx"); cookie.setMaxAge(0);//刪除同名的cookie response.addCookie(cookie); System.out.println("刪除成功"); } }
2.4 Sesson細節
1)java.lang.String getId() : 得到session編號
2)兩個getSession方法:
- getSession(true) / getSession() : 創建或得到session對象。沒有匹配的session編號,自動創 建新的session對象。
- getSession(false): 得到session對象。沒有匹配的session編號,返回null
3)void setMaxInactiveInterval(int interval) : 設置session的有效時間
session對象銷毀時間:
- 1 默認情況 3 0分 服務器自動回收
- 2 修改session回收時間
- 3 全局修改session有效時間
1 <!-- 修改session全局有效時間:分鍾 -->
2 <session-config>
3 <session-timeout>1</session-timeout>
4 </session-config>
- 4.手動銷毀session對象
void invalidate() : 銷毀session對象
4)如何避免瀏覽器的JSESSIONID的cookie隨着瀏覽器關閉而丟失的問題?
瀏覽器關閉而丟失cookie的原因是cookie的有效時間設置中參數為負整數導致,因此需求使用setMaxAge()函數將時間修正為正整數即可。
1 /**
2 * 手動發送一個硬盤保存的cookie給瀏覽器
3 */
4 Cookie c = new Cookie("JSESSIONID",session.getId());
5 c.setMaxAge(60*60);
6 response.addCookie(c);
總結:
1)會話管理: 瀏覽器和服務器會話過程中的產生的會話數據的管理。
2)Cookie技術:
- new Cookie("name","value")
- response.addCookie(coookie)
- request.getCookies()
3)Session技術
- request.getSession();
- setAttrbute("name","會話數據");
- getAttribute("會話數據")