Cookie 是 Web 开发中用于在客户端(浏览器)存储少量数据的经典机制。在 Java Servlet/JSP 中,通过 HttpServletRequest 和
HttpServletResponse 对象可以方便地对 Cookie 进行操作。理解其关键属性是正确使用的基础。

Cookie 的核心属性
name (名称):Cookie 的唯一标识符。

value (值):存储的实际数据字符串。

maxAge (最大存活时间):

正数:Cookie 将在指定秒数后过期。例如 setMaxAge(606024) 保存一天。

负数:Cookie 为会话级 Cookie,仅存在于浏览器内存中,浏览器关闭即失效。默认值为 -1。

零:立即删除该 Cookie。这是删除 Cookie 的标准方式。

path (路径):指定 Cookie 的有效 URL 路径。默认是创建该 Cookie 的页面所在目录及其子目录。设为 “/” 表示该域名下的所有路径均可访问此
Cookie。

domain (域名):指定 Cookie 有效的域名。默认是当前域名。

secure (安全标志):若为 true,则 Cookie 仅通过 HTTPS 协议传输。

httpOnly:若为 true,则 Cookie 无法通过客户端的 JavaScript document.cookie 访问,有助于防止跨站脚本攻击(XSS)窃取 Cookie。

Cookie 操作工具类实现
以下是一个包含增、删、改、查的 Cookie 工具类示例:

java
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Optional;

public class CookieUtil {

/**
 * 获取请求中的所有 Cookie
 */
public static Cookie[] getAllCookies(HttpServletRequest request) {
    return request.getCookies(); // 可能返回 null
}

/**
 * 根据名称查找指定的 Cookie
 */
public static Optional<Cookie> findCookieByName(HttpServletRequest request, String name) {
    if (name == null || name.trim().isEmpty()) {
        return Optional.empty();
    }
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        return Arrays.stream(cookies)
                     .filter(cookie -> name.equals(cookie.getName()))
                     .findFirst();
    }
    return Optional.empty();
}

/**
 * 添加/设置一个新的 Cookie
 * @param response HttpServletResponse
 * @param name Cookie 名称
 * @param value Cookie 值
 * @param maxAge 存活时间(秒)。若 <=0,通常设置为会话级(-1)或一个很大的正数。
 * @param path 有效路径,建议设为 "/"
 * @return 是否成功添加
 */
public static boolean addCookie(HttpServletResponse response,
                                 String name, String value, int maxAge, String path) {
    if (name == null || name.trim().isEmpty()) {
        return false;
    }
    Cookie cookie = new Cookie(name.trim(), value != null ? value.trim() : "");
    cookie.setMaxAge(maxAge);
    cookie.setPath(path != null ? path : "/"); // 默认根路径
    // 可选设置:cookie.setHttpOnly(true); cookie.setSecure(true);
    response.addCookie(cookie);
    return true;
}
// 简化版重载方法
public static boolean addCookie(HttpServletResponse response, String name, String value, int maxAge) {
    return addCookie(response, name, value, maxAge, "/");
}

/**
 * 删除指定名称的 Cookie
 * 原理:创建一个同名的 Cookie,将其 maxAge 设置为 0,并覆盖原 Cookie。
 */
public static boolean removeCookie(HttpServletRequest request,
                                    HttpServletResponse response,
                                    String name,
                                    String path) {
    Optional<Cookie> cookieOpt = findCookieByName(request, name);
    if (cookieOpt.isPresent()) {
        Cookie cookie = cookieOpt.get();
        cookie.setValue(""); // 清空值(可选)
        cookie.setMaxAge(0); // 关键:设置为0,让浏览器立即删除
        cookie.setPath(path != null ? path : cookie.getPath()); // 路径必须与原Cookie一致
        response.addCookie(cookie); // 覆盖原Cookie
        return true;
    }
    return false;
}
// 简化版重载方法
public static boolean removeCookie(HttpServletRequest request,
                                    HttpServletResponse response,
                                    String name) {
    return removeCookie(request, response, name, "/");
}

/**
 * 修改指定 Cookie 的值(或同时修改其他属性)
 * 注意:修改本质是“覆盖”,所以 name, path, domain 必须与原 Cookie 严格一致。
 */
public static boolean updateCookie(HttpServletRequest request,
                                    HttpServletResponse response,
                                    String name,
                                    String newValue,
                                    int newMaxAge) {
    Optional<Cookie> cookieOpt = findCookieByName(request, name);
    if (cookieOpt.isPresent()) {
        Cookie oldCookie = cookieOpt.get();
        Cookie newCookie = new Cookie(name, newValue != null ? newValue.trim() : "");
        // 以下属性必须与待覆盖的Cookie保持一致!
        newCookie.setPath(oldCookie.getPath());
        // 如果原Cookie有domain,也需要设置
        // newCookie.setDomain(oldCookie.getDomain());
        newCookie.setMaxAge(newMaxAge);
        response.addCookie(newCookie);
        return true;
    }
    return false; // 原Cookie不存在,修改失败
}

}
使用示例与注意事项
java
@WebServlet(“/test”)
public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 1. 查询
Optional userCookie = CookieUtil.findCookieByName(req, “username”);
userCookie.ifPresent(c -> System.out.println(“Found: “ + c.getValue()));

    // 2. 添加(设置有效期为7天)
    CookieUtil.addCookie(resp, "username", "张三", 60*60*24*7);

    // 3. 修改(将有效期延长)
    CookieUtil.updateCookie(req, resp, "username", "李四", 60*60*24*30);

    // 4. 删除
    CookieUtil.removeCookie(req, resp, "username");

    resp.getWriter().write("Cookie operations completed.");
}

}
‼️ 重要注意事项:

覆盖一致性原则:修改或删除一个 Cookie 时,新创建的 Cookie 的 name、path 和 domain 属性必须与想要覆盖的原 Cookie
完全一致,否则浏览器会将其视为一个不同的 Cookie,导致操作失败。

路径(Path)的重要性:很多 Cookie 操作问题都源于路径不匹配。如果不确定,在创建和删除时都将 path 明确设置为 “/”。

响应提交:必须在响应被提交(即输出流关闭)之前调用 response.addCookie()。

大小限制:每个 Cookie 大小通常限制在 4KB 左右,且每个域名下的 Cookie 数量也有限制(约 50个)。不要用 Cookie 存储大量数据。