javaWeb中cookie和session的區別與聯繫

一、cookie

1.誕生

  • Cookie是1993年由網景公司(Netscape)前僱員發明的一種進行網絡會話狀態跟蹤的技術
  • 會話是由一組請求狀態組成,請求與響應之間一定需要有數據傳遞,由此需要進行會話狀態跟蹤。然而HTTP協議是無狀態協議,在不同的請求間是無法進行數據傳遞的。此時就需要一種可以進行請求間數據傳遞的會話跟蹤技術,Cookie就是一種這樣的技術

2.簡介

  • Cookie是由服務器生成,保存在客戶端的一種信息載體。這個載體中存放着用戶訪問該站點的會話狀態信息(一般清空瀏覽器緩存會刪除這些信息)。只要Cookie沒有被清空,或者Cookie沒有失效,那麼,保存在其中的會話狀態就有效
  • 用戶在提交第一次請求後,由服務器生成Cookie,並將其封裝到響應頭中,以響應的形式發送給客戶端。客戶端接收到這個響應後,將Cookie保存到客戶端。當客戶端再次發送同類請求後,在請求中會攜帶保存在客戶端的Cookie數據,發送到服務端,由服務器對會話進行跟蹤

3.創建與添加

// 創建Cookie,key-value存儲
Cookie cookie1 = new Cookie("username", "tom");
Cookie cookie2 = new Cookie("pwd", "123");
// 向響應頭中添加Cookie
response.addCookie(cookie1);
response.addCookie(cookie2);

4.cookie屬性設置

// 創建Cookie,key-value存儲
Cookie cookie = new Cookie("username", "tom");
//生存時間,單位 秒
cookie.setMaxAge(10);
// 表示 該cookie的作用域,只有該path以及 其子路徑 才能訪問到 該cookie.  注意:這裏指定的路徑要求必須要添加上項目名稱
cookie.setPath(req.getContextPath()+"/");

5.刪除與修改cookie

// 沒有刪除, 修改,只有覆蓋
// 創建一個 和 需要修改的 cookie name相同的cookie對象, 並放入響應對象中
Cookie cookie = new Cookie("username", "tom");
response.addCookie(cookie);
// 通過 創建一個 和 需要修改的 cookie name相同的cookie對象, 並設置生存時間爲0(相當於刪除),並放入響應對象中
Cookie cookie = new Cookie("username", "");
cookie.setMaxAge(0);//相當於刪除
response.addCookie(cookie);

//設置Cookie的有效期。這個值爲一個整型值,單位爲秒
//該值大於0,表示將Cookie存放到客戶端的硬盤
//該值小於0,與不設置效果相同,會將Cookie存放到瀏覽器的緩存
//該值等於0,表示Cookie一生成,馬上失效
cookie.setMaxAge(60 * 60 * 24 * 10);    //設置Cookie的有效期爲10天(例如登錄頁面上有10天內免登錄字樣)

6.查看cookie

  • 從請求中獲取攜帶的cookie
// 獲取請求中的cookie
Cookie[] cookies = request.getCookies();
if(null != cookies){
    //遍歷cookies
  	for(Cookie cookie : cookies){
    	System.out.println(cookie.getName()+"="+cookie.getValue());
  	}
}

7.cookie特性

  • 只能保存客戶端,但產生是在服務器端
  • 只能保存字符串,使用的字符集是ISO-8859-1
  • cookie可以被禁用,禁用後cookie失效
  • 安全性較低
  • 瀏覽器保存的cookie的數據有大小限制
    • 和瀏覽器有關
    • 一般在4k左右

二、session

1.簡介

  • Session,即會話,是Web開發中的一種會話狀態跟蹤技術。當然所描述的Cookie也是一種會話跟蹤技術。不同的是Cookie是將會話狀態保存在了客戶端,而Session則是將會話狀態保存在了服務器端
  • 那麼,到底什麼是“會話”?當用戶打開瀏覽器,從發出第一次請求開始,一直到最終關閉瀏覽器,就表示一次會話的完成

2.對Session域屬性空間的操作

  • Session是一個專門用於存放數據的集合,我們一般稱這個用於存放數據的內存空間爲域屬性空間,簡稱域。HttpSession中具有三個方法,是專門用於對該域屬性空間中數據進行寫、讀操作的。
  • public void setAttribute(String name,Object value)該方法用於向Session的域屬性空間中放入指定名稱、指定值的域屬性
  • public Object getAttribute(String name)該方法用於從Session的域屬性空間中讀取指定名稱爲域屬性值
  • public void removeAttribute(String name)該方法用於從Session的域屬性空間中刪除指定名稱的域屬性(可以用於註銷某個用戶賬號)

3.獲取session

  • request.getSession()相當於request.getSession(true)

  • request.getSession(boolean flag)根據參數不同:

    • 參數爲true

      瀏覽器發送請求到服務器,服務器會根據請求檢查其中是否包含JSessionID,有JSessionID服務器會根據JSessionID查找對應的session對象,沒有找到,創建並返回一個新的session對象

    • 參數爲false

      瀏覽器發送請求到服務器,服務器會根據請求檢查其中是否包含JSessionID,有JSessionID服務器會根據JSessionID查找對應的session對象,沒有找到,返回null

4.session原理(重要)

① 寫入Session列表:

  • 服務器對當前應用中的Session是以Map的形式進行管理的,這個Map稱爲Session列表。該Mapkey爲一個32位長度的隨機串,這個隨機串稱爲JSessionID,value則爲Session對象的引用
  • 當用戶第一次提交請求時,服務端Servlet中執行到request.getSession()方法後,會自動生成一個Map.Entry對象,key爲一個根據某種算法新生成的JSessionID,value則爲新創建的HttpSession對象

在這裏插入圖片描述

在這裏插入圖片描述

② 服務器生成併發送Cookie

  • 在將Session信息寫入Session列表後,系統還會自動將“JSessionID”作爲name,這個32爲長度的隨機串作爲value,以Cookie的形式存放到響應頭中,並隨着響應,將該Cookie發送到客戶端

在這裏插入圖片描述

③ 客戶端接收併發送Cookie

  • 客戶端接收到這個Cookie後會將其存放到瀏覽器的緩存中。即,只要客戶端瀏覽器不關閉,瀏覽器緩存中的Cookie就不會消失
  • 當用戶提交第二次請求時,會將緩存中的這個Cookie,伴隨着請求的頭部信息,一塊發送到服務器

④ 從Session列表中查找

  • 服務端從請求中讀取到客戶端發送來的Cookie,並根據Cookie的JSessionID的值,從Map中查找相應key所對應的value,即Session對象。然後,對該Session對象的域屬性進行讀寫操作

在這裏插入圖片描述

以我的理解大概來講就是:

  • 當用戶第一次訪問一個具有getSession(true)代碼時,服務器會在session列表中自動創建一個Key(指的是32位長度的隨機字符串)-Value(創建的HttpSession對象:session)鍵值對
  • 然後將JSessionID作爲key和上面生成的32位長度的隨機字符串作爲value形成key-value鍵值作爲參數保存到Cookie對象中(這裏原來的32位長度的隨機字符串key變成了現在的value)
  • 客戶端再次發起同類請求會帶上緩存中的cookie,服務器接收到請求來的cookie,將其JSessionIDvalue值與session列表匹配(實際上JSessionID的value值與session列表裏其中的一個32位長度的隨機字符串的key是同一個東西),找到相應的session引用,就可以進行session域的讀寫

5.session生存時間

  • 默認情況下,生存時間爲30分鐘。(從最後一次請求開始計算,30分鐘後session會過期)
// 可以通過設置 生存時間,改變原始值
session.setMaxInactiveInterval(10);// 參數單位是 秒, 此處表示生存時間爲10秒
// 一般不會刻意的修改該值

6.url重寫

  • cookie禁用時,瀏覽器不保存JSessionID,所以瀏覽器發送請求時,其中沒有攜帶JSessionID,服務器無法獲取session,只能創建新的session返回給瀏覽器,但瀏覽器依然沒有保存。通過在請求地址後加上 ;jsessionid=EA219D35E18BC9BA1C2B9506BF498ADA 後面的值是當時返回給瀏覽器的session的id(即JSessionID)。可以手動的讓請求攜帶JSessionID,這樣服務器就可以獲取其對應的session。

  • 上面的操作太麻煩,所以提供了url重寫的方法。

// 會自動的在url後拼接當前的JSessionID
<%
  // 在傳入的url後拼接JSessionID,如果不需要拼接,則返回原始url
  String url1 = response.encodeURL(request.getContextPath()+"/jsp/t6.jsp");//一般轉發時使用此方法
  // 在傳入的url後拼接JSessionID,如果不需要拼接,則返回原始url
  String url2 = response.encodeRedirectURL("t6.jsp");// 一般重定向時使用此方法
%>
<a href="<%=url1 %>" >t6.jsp========11</a>
<a href="<%=url2 %>" >t6.jsp========22</a>
  • 禁用cookie更不安全,jsessionid會暴露在地址欄中
  • 一般cookie被禁用時,不做處理,只提示用戶,將無法使用部分功能

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章