请添加图片描述

引言:一张酒店的“早餐券”

你去酒店吃早餐,前台递给你一张纸质餐券,上面写着“房号 808”,并盖了章。你拿着这张券去餐厅,服务员看一眼券,就知道你住 808 房,可以享用免费早餐。这张餐券就是 Cookie,服务员就是 服务器

在 Java Servlet 世界里,javax.servlet.http.Cookie 类就是这张餐券的代码化身。本文将带你从零开始,掌握 Cookie 的创建、配置、获取与安全加固,写出专业级会话管理代码。


一、前置知识:Web 开发中的身份识别

HTTP 协议天生“健忘”——每次请求都是独立的,服务器不会记住两次请求之间的关系。为了让服务器认出“你是谁”,我们引入了 Cookie:服务器通过 Set-Cookie 响应头把一小段文本发送给浏览器,浏览器保存下来,后续请求自动携带。这套机制构成了 Web 会话管理的基础。


二、名词解释:认识 javax.servlet.http.Cookie

在 Java Servlet API 中,Cookie 类封装了客户端会话标识。每个 Cookie 包含:

  • 名称(Name)值(Value):核心数据,必须成对出现。
  • 属性:如 PathDomainMaxAgeHttpOnlySecure 等,控制 Cookie 的行为与安全边界。

创建 Cookie 对象:

Cookie cookie = new Cookie("sessionId", "abc123");

三、实战操作:Java 设置与获取 Cookie 的标准姿势

3.1 设置 Cookie(发送给浏览器)

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
    // 1. 创建 Cookie(注意:值应进行 URL 编码,防止特殊字符破坏格式)
    Cookie cookie = new Cookie("sessionId", URLEncoder.encode("abc123", "UTF-8"));
    
    // 2. 配置属性
    cookie.setMaxAge(3600);           // 1 小时后过期(单位秒)
    cookie.setPath("/");              // 作用于整个站点
    cookie.setHttpOnly(true);         // 禁止 JavaScript 读取,防御 XSS 攻击
    cookie.setSecure(true);           // 仅 HTTPS 传输(生产环境必须)
    // 设置 Domain(可选):允许子域共享
    cookie.setDomain(".example.com");
    
    // 3. 将 Cookie 添加到响应中
    response.addCookie(cookie);
    
    // 如果需要设置 SameSite(Servlet 5.0+ 未直接支持,手动添加响应头)
    response.setHeader("Set-Cookie", cookie.getName() + "=" + cookie.getValue() + 
            "; Path=/; HttpOnly; Secure; SameSite=Lax");
}

关键点

  • setMaxAge(0) 可立即删除同名 Cookie(需 Path 匹配)。
  • setMaxAge(-1) 表示会话级 Cookie,关闭浏览器即失效。
  • 值必须 URL 编码:因为 Cookie 值中不能包含空格、逗号、分号等特殊字符,否则浏览器会截断。

3.2 获取 Cookie(从请求中读取)

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
    Cookie[] cookies = request.getCookies();
    String sessionId = null;
    if (cookies != null) {
        for (Cookie c : cookies) {
            if ("sessionId".equals(c.getName())) {
                // 注意解码
                sessionId = URLDecoder.decode(c.getValue(), "UTF-8");
                break;
            }
        }
    }
    if (sessionId == null) {
        // 未登录或 Cookie 丢失
        response.sendRedirect("login.html");
    } else {
        // 处理业务...
    }
}
  • getCookies() 可能返回 null(无 Cookie),务必判空。
  • 若值经过 URL 编码,获取后需解码。

四、深度解析:Cookie 的生命周期与作用域

setMaxAge 含义 生命周期
正数(秒) 持久化 Cookie 存活指定秒数,关闭浏览器仍存在
负数(如 -1) 会话级 Cookie 仅在当前浏览器会话中存活,关闭即消失
0 立即删除 覆盖同名 Cookie 并使其过期

作用域控制

  • Path:决定 Cookie 在哪些 URL 路径下会被发送。例如 Path=/app 只会在 /app 及其子路径(如 /app/user)的请求中携带。
  • Domain:限制 Cookie 可被哪些域名访问。Domain=.example.com 允许 a.example.comb.example.com 共享该 Cookie。

五、安全加固:让你的 Cookie 坚不可摧

属性 作用 设置示例
HttpOnly 禁止 JavaScript 通过 document.cookie 读取,防御 XSS 攻击 cookie.setHttpOnly(true);
Secure 仅 HTTPS 加密连接下传输,防止中间人截获 cookie.setSecure(true);
SameSite 限制跨站请求携带,防御 CSRF(Servlet 5.0+ 需手动添加响应头) response.setHeader("Set-Cookie", "...; SameSite=Lax");

重要:生产环境必须为身份凭证 Cookie 同时启用 HttpOnlySecure,并配置 SameSite


六、排障手册:常见误区与避坑指南

误区 / 问题 正确做法
设置 Cookie 后无法读取 检查 Path 是否匹配:设置时 Path=/app,读取时请求 URL 必须在 /app 及其子路径下。
删除 Cookie 失败 必须用完全相同 PathDomain 的同名 Cookie,调用 setMaxAge(0) 覆盖。
中文乱码 存入时 URLEncoder.encode(value, "UTF-8"),取出时 URLDecoder.decode(value, "UTF-8")
Cookie 未生效(无响应头) 确认代码执行了 response.addCookie(cookie),且未在之前调用 response.sendRedirect 等操作。
超出大小限制 单个 Cookie 不超过 4KB,单域名不超过 20-50 个。超限会被浏览器静默丢弃。

七、总结

步骤 要点
创建 new Cookie(name, value),值建议 URL 编码
配置 setMaxAgesetPathsetHttpOnlysetSecure 等按需设置
下发 response.addCookie(cookie)
获取 request.getCookies() 遍历查找
删除 同名 + 同 Path + setMaxAge(0) 覆盖

一句话总结:Cookie 是 Servlet 中维持用户会话的基础武器。掌握 Cookie 类的属性配置与生命周期,配合 HttpOnlySecureSameSite 等安全加固,就能写出健壮、安全的会话管理代码。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐