SpringBoot高級開發(9)Spring中的HttpSession
1、簡述
HttpSession是javaWeb提供的,用來處理會話事務的。session數據保存在后臺,當然首次開啟會話(即調用req.getSession())的時候也會將該SessionID數值傳給前端用作Cookie
2、作用范圍
(1)首次訪問服務器開始,瀏覽器關閉后就結束。
(2)Cookie層面沒有過期時間,這個一個會話,expire的標識就是會話。且自動設置了HttpOnly。

【如果 Cookie 不包含到期日期,則將其視為會話 Cookie。會話 Cookie 存儲在內存中,永遠不會寫入磁盤,當瀏覽器關閉時,此后 Cookie 將永久丟失。】
(3)后端的Session可以存儲30分鐘,如果30分鐘無任何請求,就自動刪除。期間有請求,就刷新過期時間。
3、流程
假設后端一個接口如下
@RequestMapping("/test")
public HashMap<String,Object> test(HttpServletRequest req) {
HttpSession session = req.getSession();
session.setAttribute("test", "no");
return XXXXX;
}
step1:前端首次訪問/test,此時請求頭不帶任何Cookie。后端test函數接收到請求后,由于調用了req.getSession()函數,所以后端會創建一個session對象保存在后臺,并且在請求返回之后自動給前端植入一個JSESSIONID=XXXXX的Cookie
step2:前端第二次訪問的時候,此時請求頭自動攜帶了JSESSION=XXXX的Cookie數據。此時后端的session就是step1中產生的session對象,對量里可以通過setAttr和getAttr來讀寫基于這個用戶的數據。
step3:如果用戶關閉瀏覽器。那么前端的這個JSESSIONID得Cookie就沒了。后端的session對象,如果30分鐘無任何請求,就自動刪除。
此過程中,前端什么都不用做。
4、Session的缺點
(1)不適合負載均衡的場景
比如 A 服務器存儲了 Session,就是做了負載均衡后,假如一段時間內 A 的訪問量激增,會轉發到 B 進行訪問,但是 B 服務器并沒有存儲 A 的 Session,會導致 Session 的失效。
5、Session和Cookie的區別
這個主體,其實嚴格來講是存在歧義的,或者這個問題就不該討論。因為Session的實現方式本身就是通過Cookie實現的。不過如果忽略底層實現,是考慮抽象的上層,那么可以假設Session將用戶的數據【userName age 等】保存在server端,Cookie將用戶的數據【userName age 等】保存在Client端(實際大部分場景,Cookie跟Session一樣,在Cookie只保存一個token串,不過這里就不鉆牛角尖了)。
基于此,兩者區別為:
(1)作用范圍不同,Cookie 保存在客戶端(瀏覽器),Session 保存在服務器端。
(2)存取方式的不同,Cookie 只能保存String,Session 可以存任意數據類型。
(3)有效期不同,Cookie 可設置為長時間保持,比如我們經常使用的默認登錄功能,Session 一般失效時間較短,客戶端關閉或者 Session 超時都會失效。
(4)隱私策略不同,Cookie 存儲在客戶端,比較容易遭到不法獲取,早期有人將用戶的登錄名和密碼存儲在 Cookie 中導致信息被竊取;Session 存儲在服務端,安全性相對 Cookie 要好一些。
(5)存儲大小不同, 單個 Cookie 保存的數據不能超過 4K,同一域名下的cookie好像是20個。 Session 可存儲數據遠高于 Cookie,基本無限制。
(6)session的數據默認保存在內存里,通過get/getAttribute(),不過我們也可以自己構建后端存儲方式,例如mysql,redis
6、HttpSession中的線程安全如何保證的?
暫未研究。
參考:
https://zhuanlan.zhihu.com/p/665717576
https://blog.csdn.net/m0_63217468/article/details/127426397

浙公網安備 33010602011771號