我将为你详细解释在两种最主流的 Java Web 开发场景中如何设置 Cookie 时间:

- 原生 Servlet API (适用于任何 Java Web 应用,如 Tomcat, Jetty)
- Spring Boot (目前最流行的 Java 框架)
核心概念:Cookie 的有效期类型
在设置时间之前,需要理解 Cookie 有两种主要的有效期类型:
-
会话 Cookie (Session Cookie)
- 特点:没有设置
maxAge属性,它的生命周期与用户的浏览器会话(Session)绑定。 - 行为:当用户关闭浏览器时,这个 Cookie 会被自动删除,它不会存储在用户的硬盘上,而是保存在内存中。
- 设置方式:在 Java 代码中,当你创建
Cookie对象后,不调用setMaxAge()方法,或者调用setMaxAge(-1),它就会成为会话 Cookie。
- 特点:没有设置
-
持久化 Cookie (Persistent Cookie)
- 特点:通过设置
maxAge属性来指定其存活时间(以秒为单位)。 - 行为:即使浏览器关闭,只要 Cookie 没有过期,它就会一直存储在用户的硬盘上,下次用户打开浏览器时,Cookie 仍然会随请求发送到服务器。
- 设置方式:在 Java 代码中,调用
cookie.setMaxAge(seconds)。
- 特点:通过设置
使用原生 Servlet API
这是最基础的方式,理解了它,有助于你理解 Cookie 的工作原理。

关键方法:cookie.setMaxAge(int seconds)
- 参数
seconds:- 正数:指定 Cookie 存活的时间(秒)。
60 * 60 * 24 * 7表示一周。 - 零 (
0):立即删除该 Cookie,这通常用于注销登录或清除特定偏好设置。 - 负数 (
-1):表示这是一个会话 Cookie,将在浏览器关闭时被删除,这是默认行为。
- 正数:指定 Cookie 存活的时间(秒)。
示例代码
假设你有一个 Servlet,需要在用户登录后设置一个名为 userToken 的 Cookie,有效期为一周。
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 模拟登录成功
String username = request.getParameter("username");
// ... 验证逻辑 ...
// 2. 创建 Cookie 对象
Cookie userTokenCookie = new Cookie("userToken", "some_unique_token_string_" + username);
// 3. 设置 Cookie 的有效期为一周 (单位:秒)
// 一周 = 7天 * 24小时 * 60分钟 * 60秒
int oneWeekInSeconds = 7 * 24 * 60 * 60;
userTokenCookie.setMaxAge(oneWeekInSeconds);
// 4. (可选但推荐) 设置 Cookie 的路径
// 这表示只有访问 "/app" 路径及其子路径时,浏览器才会携带这个 Cookie
// 如果不设置,默认是当前 Servlet 的路径,可能导致在某些页面下 Cookie 不会被发送
userTokenCookie.setPath("/");
// 5. 将 Cookie 添加到 HTTP 响应中
response.addCookie(userTokenCookie);
// 6. 重定向到主页
response.sendRedirect("/home.jsp");
}
}
如何从客户端读取 Cookie?
// 在另一个 Servlet 或 JSP 页面中
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("userToken".equals(cookie.getName())) {
String token = cookie.getValue();
// 使用这个 token 进行后续操作...
System.out.println("Found user token: " + token);
break; // 找到后就可以退出了
}
}
}
使用 Spring Boot
Spring Boot 对 Servlet API 进行了封装,提供了更简洁、更强大的方式来操作 Cookie。
使用 HttpServletResponse (与原生 Servlet 类似)
在 Controller 方法中,你可以直接注入 HttpServletResponse,然后使用它的 addCookie 方法,底层仍然是创建 Cookie 对象。
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@PostMapping("/login")
public String login(@RequestParam String username, HttpServletResponse response) {
// 1. 创建 Spring 封装的 Cookie 对象 (org.springframework.web.server.ServerWebExchange 下的,但通常用 javax.servlet 的)
// 为了清晰,我们直接使用 javax.servlet 的 Cookie
Cookie userTokenCookie = new Cookie("userToken", "spring_boot_token_" + username);
// 2. 设置有效期 (一周)
userTokenCookie.setMaxAge(7 * 24 * 60 * 60);
// 3. 设置路径
userTokenCookie.setPath("/");
// 4. 添加到响应
response.addCookie(userTokenCookie);
return "Login successful! Cookie has been set.";
}
@PostMapping("/logout")
public String logout(HttpServletResponse response) {
// 1. 创建一个同名但立即过期的 Cookie 来删除它
Cookie deleteCookie = new Cookie("userToken", null);
deleteCookie.setMaxAge(0); // 设置为 0,立即删除
deleteCookie.setPath("/");
// 2. 添加到响应
response.addCookie(deleteCookie);
return "Logged out successfully! Cookie has been removed.";
}
}
使用 ResponseCookie (Spring 5 推荐的方式)
ResponseCookie 是 Spring 提供的一个更现代化、功能更丰富的 Cookie 类,它构建器模式,链式调用非常方便,并且能更好地处理编码、安全属性等。
import org.springframework.http.ResponseCookie;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/api/auth")
public class AuthControllerWithResponseCookie {
@PostMapping("/login-modern")
public String loginModern(@RequestParam String username, HttpServletResponse response) {
// 使用 ResponseCookie.Builder 来构建 Cookie
ResponseCookie cookie = ResponseCookie.from("userToken", "modern_token_" + username)
.path("/") // 设置路径
.maxAge(7 * 24 * 60 * 60) // 设置有效期 (一周)
.httpOnly(true) // 防止 XSS 攻击,禁止 JavaScript 访问
.secure(true) // 仅在 HTTPS 连接下发送,增强安全性
.sameSite("Lax") // 控制跨站请求,防止 CSRF 攻击
.build();
// 将 Cookie 添加到响应头中
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
return "Login successful! Modern cookie has been set.";
}
}
ResponseCookie 的优势:
- 链式调用:代码更清晰、易读。
- 安全性:可以方便地设置
HttpOnly、Secure、SameSite等重要的安全属性。 - 编码处理:能更好地处理 Cookie 值中的特殊字符。
总结与最佳实践
| 特性 | 原生 Cookie |
Spring ResponseCookie |
备注 |
|---|---|---|---|
| 易用性 | 基础,需要单独设置每个属性 | 高,构建器模式,链式调用 | ResponseCookie 更现代化 |
| 安全性 | 需要手动设置 HttpOnly, Secure |
内置支持,可轻松设置 | 强烈推荐使用 HttpOnly 和 Secure |
| 适用场景 | 任何 Java Web 环境 | Spring 5+ 项目 | 在 Spring 项目中优先使用 ResponseCookie |
| 删除 Cookie | setMaxAge(0) |
maxAge(0) |
两者方式一致 |
最佳实践建议:
- 明确有效期:根据业务需求明确你需要的是会话 Cookie 还是持久化 Cookie。
- 设置合理的路径:始终使用
setPath("/")或一个更具体的路径,避免 Cookie 被不必要地发送,提高性能和安全性。 - 安全性第一:
HttpOnly:Cookie 包含敏感信息(如认证令牌),必须设置为true,以防止跨站脚本攻击 窃取 Cookie。Secure:在生产环境中,强烈建议设置为true,确保 Cookie 只通过 HTTPS 连接传输。SameSite:设置为Lax或Strict可以有效防御 CSRF(跨站请求伪造)攻击。Lax是一个比较平衡的选择。
- 在 Spring 中使用
ResponseCookie:如果你在使用 Spring Boot,请优先考虑使用ResponseCookie,它能让你更安全、更优雅地管理 Cookie。
