一, 业务场景:为什么 HTTP 需要"记忆力"?
设想你在开发一个电商平台。
-
场景 A:用户浏览了"某一件衣服",将其加入购物车。
-
场景 B:用户点击"去结算"。
由于 HTTP 协议 (HyperText Transfer Protocol) 是无状态 (Stateless) 的,服务器处理场景 B 时,并不知道这个用户在场景 A 中做了什么。如果没有状态保持机制,用户每次点击页面都需要重新登录。
为了解决这个问题,Web 开发引入了 Cookie 和 Session。
二,.技术原理与核心机制
2.1 Cookie:客户端存储协议
Cookie 是由服务器发送并存储在用户客户端上的小型文本文件。
-
工作流:
-
浏览器请求服务器。
-
服务器在响应头中包含
Set-Cookie指令。 -
浏览器保存 Cookie。
-
后续请求时,浏览器自动在请求头
Cookie字段中携带该数据。
-
既然Cookie是一个文本文件,那自然可以用于存储数据,这是否意味着我们可以使用Cookie把我们每次登录的账号密码存储在Cookie中呢?
其实这是不对的,Cookie是一个小型文本文件,其根本目的是为了标识身份,而非存储数据. 这里也就涉及到Cookie的功能 : 它到底存什么?
我们每次登录的账号密码并非存在Cookie文件中,而是以一种Session ID(会话令牌),试想一下账号密码必然不可能以明文的形式存储. Session ID的主要功能如下:
2.2 Session:服务端会话管理
Session 是存储在服务器端的上下文数据结构。
-
工作流:
-
用户登录,服务器创建 Session 对象,并生成唯一的 Session ID。
-
服务器通过 Cookie 将 Session ID 发送给浏览器。
-
浏览器后续请求携带该 ID。
-
服务器根据 ID 检索对应的存储数据,识别用户身份。
-
大致流程图如下:

2.3 核心对比表
| 维度 | Cookie | Session |
|---|---|---|
| 存储位置 | 客户端 (浏览器) | 服务端 (内存/数据库/Redis) |
| 安全性 | 较低 (易被伪造/拦截) | 较高 (敏感数据不离开服务器) |
| 存储容量 | 限制约 4KB | 取决于服务器硬件/配置 |
| 生命周期 | 可设置过期时间 (持久化) | 通常随浏览器关闭或超时失效 |
| 性能消耗 | 几乎不占用服务器资源 | 大量并发时占用服务器内存 |
三,Spring MVC 模拟接口实现
1. 技术栈模型 (Technical Stack)
-
后端: SpringMVC (Controller 层)
-
存储 :
HttpSession(默认内存存储) -
验证: 基于 POJO 的请求参数绑定
2. 核心代码实现
2.1 用户凭证对象 (User DTO)
使用json数据传输对象 接收前端请求。创建一个实体类LoginRequest ,存储输入信息,构建对象
java
import lombok.Data;
@Data
public class LoginRequest {
private String userName;
private String passWord;
}
2.2 登录控制器 (Login Controller)
演示如何注入 HttpSession 并实现登录/校验逻辑。
java
import jakarta.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/userLogin")
public class LoginController {
//1.登录接口
@PostMapping("/login")
public String login(@RequestBody LoginRequest request, HttpSession session){
//模拟数据库数据校验
if("cheems".equals(request.getUserName()) && "123456".equals(request.getPassWord())){
//登录成功
session.setAttribute("loginUser",request.getUserName());
//设置Session最大存储时间
session.setMaxInactiveInterval(3600);
return String.format("登录成功,欢迎回来! %s",request.getUserName());
}
return "账号或密码不正确";
}
//2.获取当前登录状态
@GetMapping("checkLogin")
public String checkLogin(HttpSession session){
//从session中检索Session_ID
Object userName = session.getAttribute("loginUser");
//如果为空
if(userName == null){
return "未登录或会话已过期";
}else{
return "当前登录用户: " + userName.toString();
}
}
}
验证登录接口:


验证检查登录状态接口:

通过以上的演示,可以看到通过Session和Cookie的配合,以及HttpSession的使用,使得http协议具有了状态保持的相关功能解决了http无状态的缺陷
下面是其中的职责与分工
| 组件 | 核心职责 | 隐喻 |
|---|---|---|
| HttpSession | 在服务器内存中开辟的一块专属于该用户的"储物柜"。 | 银行内部的保险柜。 |
| JSESSIONID | 唯一标识该储物柜的"钥匙编号"。 | 保险柜的钥匙编号。 |
| Cookie | 负责在每次请求时把"钥匙编号"递给服务器。 | 客户手中的存折/回单。 |
3. 运行机制拆解 (Mechanism Analysis)
-
Set-Cookie 响应 : 当执行
session.setAttribute时,如果这是新会话,SpringMVC 底层的 Servlet 容器(如 Tomcat)会在响应头中自动添加Set-Cookie: JSESSIONID=xxxxxx; Path=/; HttpOnly。 -
自动携带 : 浏览器接收到后,后续对该域名的所有请求都会在 Request Header 中自动携带
Cookie: JSESSIONID=xxxxxx。 -
匹配与提取 : SpringMVC 接收到请求后,根据
JSESSIONID从服务器内存的 Session Map 中提取对应的HttpSession对象,开发者即可直接通过session.getAttribute获取数据。

以上就是有关Cookie和Session的相关介绍,如有纰漏还请指出