各位看官,大家早安午安晚安呀~~~
如果您覺得這篇文章對您有幫助的話
歡迎您一鍵三連,小編盡全力做到更好
歡迎您分享給更多人哦
今天我們來學習:Cookie/Session
1.Cookie/Session的簡述
我們在講解HTTP協議的時候已經講解過Cookie了
HTTP 協議自身是屬于 "無狀態" 協議.
"無狀態" 的含義指的是:
默認情況下 HTTP 協議的客戶端和服務器之間的這次通信, 和下次通信之間沒有直接的聯系(不冪等).
但是實際開發中, 我們很多時候是需要知道請求之間的關聯關系的.
例如登陸網站成功后, 第?次訪問的時候服務器就能知道該請求是否是已經登陸過了(不然我每次登錄軟件,都要輸入賬戶密碼真的是太費勁了)
1.1回顧 Cookie
Cookie:瀏覽器在本地存儲數據的一種方式。
現代瀏覽器設計時,會避免網頁直接訪問計算機的文件系統,因此,瀏覽器封裝了操作文件的API,瀏覽器作為中間層,管理所有Cookie的讀寫操作。網頁不能直接訪問文件系統。
上述的令牌(SessionID)就通常存放在Cookie中
我們每一次訪問服務器的時候就要帶上Cookie(不管服務器要不要都會帶上)
1.2.理解Session
Session:Session 是服務器端保存用戶信息的?種機制.
也可以這么說:Session是服務器為了保存用戶信息而創建的?個特殊的對象(本質上就是一個哈希表)
服務器同?時刻收到的請求是很多的. 服務器需要清楚的區分每個請求是從屬于哪個用戶,?也就是屬于哪個會話,?就需要在服務器這邊記錄每個會話以及與用戶的信息的對應關系.

1.3.Cookie和Session的區別
- Cookie 是客戶端保存用戶信息的?種機制.
- Session 是服務器端保存用戶信息的?種機制.
- Cookie 和 Session之間主要是通過 SessionId 關聯起來的, SessionId 是 Cookie 和 Session 之間的橋梁。
- Cookie 和 Session 經常會在一起配合使用. 但是不是必須配合。Session 中的sessionId 也不需要非得通過 Cookie/Set-Cookie 傳遞, 比如通過URL傳遞.
1.4.domain
在 HTTP Cookie 中,domain?是一個非常重要的屬性,它決定了?Cookie 的作用域,即哪些域名可以訪問這個 Cookie。通過設置?domain
,你可以控制 Cookie 在哪些域名下生效。
譬如你給這個Cookie的domian是:127.0.0.1那么這個Cookie就只能在127.0.0.1(自己主機)下生效
直接理解:這個domain就是一個域名(給一個Cookie設置上這個域名(domain),這個Cookie就只能在這個域名下生效))
1.5.Cookie各個字段的解析

ID=20
- 含義:這是 Cookie 的核心數據,由鍵值對組成(
ID
?是名稱,20
?是值)。- 作用:通常用于標識用戶會話(如登錄狀態、用戶 ID)或存儲自定義數據,具體含義由網站后臺邏輯決定。
Path=/
- 含義:指定 Cookie 的有效路徑。
/
?表示根路徑,即該 Cookie 對網站所有路徑(如?/page1
、/api/data
)均有效。- 示例:若設置為?
Path=/admin
,則 Cookie 僅在訪問?https://example.com/admin
?及子路徑時生效。Expires=Sat, 04 Jul 2026 07:05:02 GMT
- 含義:Cookie 的過期時間(GMT 格式)。若未設置該字段,Cookie 會在瀏覽器關閉時過期(會話級 Cookie)。
- 作用:控制 Cookie 的存儲時長,超過時間后瀏覽器會自動刪除。
其他常見字段(可能未顯示但重要)
- Domain:你設置的?
127.0.0.1
?即為此字段,下文詳細說明。- Secure:若存在,說明 Cookie 僅在 HTTPS 連接下有效。
- HttpOnly:防止 JavaScript 讀取 Cookie,提升安全性
domain具體解析:
?Domain 定義
- 本質:指定 Cookie 允許發送的目標域名或 IP 地址。
- 示例:
- 若設置為?
Domain=example.com
,Cookie 會在訪問?example.com
?及其子域名(如?sub.example.com
)時發送。- 你設置的?
127.0.0.1
?是本地回環地址,代表僅對當前主機(本地開發環境)有效。2.?Domain 匹配規則(本質就是域名和路徑匹配的? (或則子域名)時,才能訪問到這個cookie)
- 嚴格匹配:Cookie 僅在請求域名與?
Domain
?完全一致或為其子域名時發送。
- 例如:
Domain=127.0.0.1
?不會在請求?localhost
?時發送(盡管兩者可能指向同一主機,但域名不同)。- 安全限制:
- 不能跨域名設置 Cookie(如?
example.com
?無法為?google.com
?設置 Cookie)。- 子域名可訪問父域名的 Cookie(如?
sub.example.com
?可讀取?Domain=example.com
?的 Cookie),但反之不行。3.?本地開發場景的 Domain 應用
- 場景:在 Postman 中測試本地服務(如?
http://127.0.0.1:8080
)時,設置?Domain=127.0.0.1
?可確保 Cookie 僅在請求該地址時生效,避免干擾其他服務。- 對比:若設置為?
Domain=localhost
,則 Cookie 會在請求?localhost
?時生效,需根據服務實際綁定的域名 / IP 選擇。
總之:
Cookie 工作原理總結
- 發送機制:當瀏覽器訪問符合?
Domain
?和?Path
?條件的地址(或則子域名)時,自動攜帶對應 Cookie 到請求頭中。- 用途:用于狀態保持(如登錄)、用戶偏好存儲、跟蹤用戶行為等。
- 安全提示:
- 生產環境中避免將敏感數據(如密碼)存入 Cookie。
- 合理設置?
HttpOnly
?和?Secure
?字段,防止 XSS 攻擊和中間人竊密。
2.如何獲得Cookie和Session
2.1獲得Cookie的兩種方法
先聲明:Spring MVC是基于 Servlet API 構建的原始 Web 框架, 也是在Servlet的基礎上實現的。
首先介紹兩個類:
- HttpServletRequest :包含了HTTP請求中的所有信息(當然也包括Cookie(還有Cookie中的SessionID))
- HttpServletResponse:包含了HTTP響應里面的所有信息
比如向客戶端發送的數據, 響應頭, 狀態碼等. 通過這個對象提供的方法, 可以獲得服務器響應的所有內容
看似這兩個類十分的強大(其實就是很強大哈哈),但是我們使用這兩個類的時候還是會頻繁地出現一些相似的代碼(不是很方便)。于是Spring MVC在這兩個對象的基礎上進行了封裝, 給我們提供更加簡單的使用方法(只是封裝,但是本質上Spring MVC本質上還是從這兩個類里面拿到數據,只是我們省事了)
2.1.1.使用HttpServletRequest獲得Cookie的方法
@RequestMapping("/getCookie")public String getCookie(HttpServletRequest request, HttpServletResponse response) { //這兩個參數不用傳//因為這兩個參數是Spring里面內置的對象,用的話需要聲明,不需要就不用聲明/* 本質上Spring也是直接從這兩個類里拿的參數,就譬如這個拿參數就太傳統了String name = request.getParameter("name");*///響應里面有什么response里面就有什么,我們想響應什么我們直接設置就好了//拿到CookieCookie[] cookies = request.getCookies();if (cookies != null) {Arrays.stream(cookies).forEach(ck -> System.out.println(ck.getName() + ";" + ck.getValue()));return "獲取Cookie成功";}return "cookie為空";}
結果:可以看到Cookies為空(默認情況下,第一次訪問時,瀏覽器默認不會攜帶任何 Cookie。?request.getCookies()
?返回?null
,不會打印任何內容。?)
我們可以手動設置Cookie,其實這也是一種作弊的體現(其實我們也能修改SessionID,但是服務器沒有這個SessionID也是白搭)
如何手動設置Cookie呢?
然后Header就會出現一個Cookie
然后就獲取Cookie成功了
2.1.2.利用注解@CookieValue
@RequestMapping("/getCookie2") //直接通過注解的方式來獲取,注解里面的值就是要獲取的Cookie值public String getCookie2(@CookieValue("name") String name) {return "獲取的Cookie- name" + name;}
結果:
設置Cookie還是很困難的,有興趣的話大家可以自行學習哦~~
2.2.設置Session的三種方法
傳統的獲得Cookie的方法需要request.getCookies();(問就是)
這個我還要看,但不是現在
Spring還提供了一個內置類,直接獲得Session對象--HttpSession
2.2.1.使用HttpServletRequest獲得Session的方法
如何從Cookie中先拿到SessionID,根據SessionID獲取Session對象,如果一開始沒有Session,就會創建一個Session對象。獲取Session里面的屬性,前提是要有。但是Session是服務器用來存儲用戶信息的地方,我們沒辦法進行偽造,只能進行設置
@RequestMapping("/getSession1") //直接通過注解的方式來獲取,注解里面的值就是要獲取的Cookie值public String getSession1(HttpServletRequest request) {//從Cookie中先拿到SessionID,根據SessionID獲取Session對象,如果一開始沒有Session,就會創建一個Session對象HttpSession session = request.getSession();//獲取Session里面的屬性,前提是要有。但是Session是服務器用來存儲用戶信息的地方,我們沒辦法進行偽造,只能進行設置String name = (String) session.getAttribute("name"); // 獲取name屬性// 要進行強轉一下,我們獲取到的都是Object對象return "從session獲得值: "+name;}
結果:
然后我們直接設置一下Session,代碼實現:
@RequestMapping("/setSession1") //直接通過注解的方式來獲取,注解里面的值就是要獲取的Cookie值public String setSession1(HttpServletRequest request) {HttpSession session = request.getSession(); // 一樣的先拿Session對象session.setAttribute("name","zhangsan"); // 我們這里設置什么都可以畢竟是設置成Object類,當然獲取到的也是Object類return "設置session成功";}
然后再獲得一下Session:
2.2.2.HttpSession獲得Session的方法
@RequestMapping("/setSession2")public String setSession1(HttpSession session) { // 直接利用session對象session.setAttribute("name","zhangsan");return "設置session成功";}
2.2.3.@SessionAttribute注解的方法獲得Session
@RequestMapping("/getSession3")public String getSession3(@SessionAttribute("name") String name) {return "username:"+name;}
2.3.設置Session的兩種方法
2.3.1.HttpselvertResponse設置Session
上面第一種獲得Session方法我們已經演示過(設置完SessionID會發生變化)
@RequestMapping("/setSession1") //直接通過注解的方式來獲取,注解里面的值就是要獲取的Cookie值public String setSession1(HttpServletRequest request) {HttpSession session = request.getSession(); // 一樣的先拿Session對象session.setAttribute("name","zhangsan"); // 我們這里設置什么都可以畢竟是設置成Object類,當然獲取到的也是Object類return "設置session成功";}
2.3.2.利用HttpSession設置Session
@RequestMapping("/setSession2")public String setSession1(HttpSession session) { // 直接利用session對象session.setAttribute("name","zhangsan");return "設置session成功";}
3.如何獲得和設置請求頭
3.1傳統獲取 header
@RequestMapping("/getHeader1")public String getHeader1(HttpServletRequest request){ //直接使用內置對象來String userAgent = request.getHeader("User-Agent");return "User-Agent:"+userAgent;}
3.2.注解@RequestHeader
@RequestMapping("/getHeader2")public String getHeader2(@RequestHeader("User-Agent") String userAgent) {return "userAgent:"+userAgent;}
4.響應
直接打印?Cookie
?對象的問題,遍歷數組并打印每個?Cookie
?對象時:
for (Cookie ck : cookies) {System.out.println(ck); // 輸出:jakarta.servlet.http.Cookie@e2b7326c }
不管是 cookies.toString()還是Arrays.toString(cookies),還是sout(Cookies)都需要Cookie中實現了自己的toString方法,不然就是打印的
類名+哈希值(jakarta.servlet.http.Cookie@e2b7326c)
原因:
Cookie
?類沒有重寫?toString()
?方法,默認調用?Object.toString()
,返回?類名@哈希值
。解決方案:手動輸出?
Cookie
?的屬性(如?getName()
?和?getValue()
)。
在我們前面的代碼例子中,都已經設置了響應數據, Http響應結果可以是數據, 也可以是靜態頁面。也可以針對響應設置狀態碼, Header信息等
上述就是Cookie(搭配domain)/Session(搭配HttpServletRequest+HttpSession)的全部內容啦,不知道您對文章中的問題和思想是否都學會理解了呢?
能看到這里相信您一定對小編的文章有了一定的認可。
有什么問題歡迎各位大佬指出
歡迎各位大佬評論區留言修正~~