在 Java Servlet 中如何设置和获取 Cookie?
·

Java Servlet 实战:手把手教你玩转 Cookie 会话管理
引言:一张酒店的“早餐券”
你去酒店吃早餐,前台递给你一张纸质餐券,上面写着“房号 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):核心数据,必须成对出现。
- 属性:如
Path、Domain、MaxAge、HttpOnly、Secure等,控制 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.com和b.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 同时启用 HttpOnly 和 Secure,并配置 SameSite。
六、排障手册:常见误区与避坑指南
| 误区 / 问题 | 正确做法 |
|---|---|
| 设置 Cookie 后无法读取 | 检查 Path 是否匹配:设置时 Path=/app,读取时请求 URL 必须在 /app 及其子路径下。 |
| 删除 Cookie 失败 | 必须用完全相同 Path、Domain 的同名 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 编码 |
| 配置 | setMaxAge、setPath、setHttpOnly、setSecure 等按需设置 |
| 下发 | response.addCookie(cookie) |
| 获取 | request.getCookies() 遍历查找 |
| 删除 | 同名 + 同 Path + setMaxAge(0) 覆盖 |
一句话总结:Cookie 是 Servlet 中维持用户会话的基础武器。掌握 Cookie 类的属性配置与生命周期,配合 HttpOnly、Secure、SameSite 等安全加固,就能写出健壮、安全的会话管理代码。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)