[SpringMVC]Cookie 和Session 从无状态协议到状态保存实务

一, 业务场景:为什么 HTTP 需要"记忆力"?

设想你在开发一个电商平台。

  • 场景 A:用户浏览了"某一件衣服",将其加入购物车。

  • 场景 B:用户点击"去结算"。

由于 HTTP 协议 (HyperText Transfer Protocol)无状态 (Stateless) 的,服务器处理场景 B 时,并不知道这个用户在场景 A 中做了什么。如果没有状态保持机制,用户每次点击页面都需要重新登录。

为了解决这个问题,Web 开发引入了 CookieSession


二,.技术原理与核心机制

2.1 Cookie:客户端存储协议

Cookie 是由服务器发送并存储在用户客户端上的小型文本文件

  • 工作流

    1. 浏览器请求服务器。

    2. 服务器在响应头中包含 Set-Cookie 指令。

    3. 浏览器保存 Cookie。

    4. 后续请求时,浏览器自动在请求头 Cookie 字段中携带该数据。

既然Cookie是一个文本文件,那自然可以用于存储数据,这是否意味着我们可以使用Cookie把我们每次登录的账号密码存储在Cookie中呢?

其实这是不对的,Cookie是一个小型文本文件,其根本目的是为了标识身份,而非存储数据. 这里也就涉及到Cookie的功能 : 它到底存什么?

我们每次登录的账号密码并非存在Cookie文件中,而是以一种Session ID(会话令牌),试想一下账号密码必然不可能以明文的形式存储. Session ID的主要功能如下:

2.2 Session:服务端会话管理

Session 是存储在服务器端的上下文数据结构。

  • 工作流

    1. 用户登录,服务器创建 Session 对象,并生成唯一的 Session ID

    2. 服务器通过 Cookie 将 Session ID 发送给浏览器。

    3. 浏览器后续请求携带该 ID。

    4. 服务器根据 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)

  1. Set-Cookie 响应 : 当执行 session.setAttribute 时,如果这是新会话,SpringMVC 底层的 Servlet 容器(如 Tomcat)会在响应头中自动添加 Set-Cookie: JSESSIONID=xxxxxx; Path=/; HttpOnly

  2. 自动携带 : 浏览器接收到后,后续对该域名的所有请求都会在 Request Header 中自动携带 Cookie: JSESSIONID=xxxxxx

  3. 匹配与提取 : SpringMVC 接收到请求后,根据 JSESSIONID 从服务器内存的 Session Map 中提取对应的 HttpSession 对象,开发者即可直接通过 session.getAttribute 获取数据。

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

相关推荐
Bruce_Liuxiaowei3 小时前
2026年4月第2周网络安全形势周报(3)
网络·安全·web安全
zl_dfq4 小时前
计算机网络 之 【IP协议】(IPv4报文格式、IP地址、公网IP VS 私网IP、路由VS转发)
网络·计算机网络·ip
大数据新鸟4 小时前
NIO 三大核心组件
服务器·网络·nio
添砖java‘’4 小时前
网络层IP
网络·网络协议·tcp/ip·ip
芯智工坊5 小时前
第19章 Mosquitto完整项目实战
网络·人工智能·mqtt·开源
灰子学技术6 小时前
Envoy 底层 TCP 交互、UDS 和事件驱动技术文档
网络·网络协议·tcp/ip
wifi chicken6 小时前
wifi漫游(Roaming)802.11kvr 全协议梳理
网络·wifi·内核开发·wifi 漫游
MAXrxc6 小时前
VRRP初体验
网络
qq_260241237 小时前
将盾CDN:移动网络环境下的安全接入技术
网络·安全