基於 Spring MVC 的 HttpServletRequest/HttpServletResponse 封裝 Cookie 常用操作,並提供通用工具類簡化開發。
@RequestMapping("/showCookies")
public void showCookies(HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies(); // 僅包含 name 和 value,無 maxAge/path/domain
if (cookies == null) {
System.out.println("沒有 Cookie");
return;
}
for (Cookie cookie : cookies) {
System.out.println("name:" + cookie.getName() + ", value:" + cookie.getValue());
}
}
注意:瀏覽器發送 Cookie 時不包含 maxAge, path, domain 等屬性,服務端無法讀取這些元數據。
@RequestMapping("/addCookie")
public void addCookie(HttpServletResponse response, String name, String value) {
Cookie cookie = new Cookie(name.trim(), value.trim());
cookie.setMaxAge(30 * 60); // 30 分鐘,單位秒;-1 為會話級,0 為刪除
cookie.setPath("/"); // 生效路徑,必須與刪除/修改時一致
response.addCookie(cookie);
System.out.println("已添加 Cookie: " + name);
}
@RequestMapping("/editCookie")
public void editCookie(HttpServletRequest request, HttpServletResponse response, String name, String value) {
Cookie[] cookies = request.getCookies();
if (cookies == null) return;
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
// 關鍵:新建 Cookie 時,name/path/domain 必須與原 Cookie 完全一致,瀏覽器才會覆蓋
Cookie newCookie = new Cookie(name, value);
newCookie.setPath("/");
newCookie.setMaxAge(30 * 60);
response.addCookie(newCookie);
System.out.println("已修改 Cookie: " + name + " -> " + value);
break;
}
}
}
@RequestMapping("/delCookie")
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
Cookie[] cookies = request.getCookies();
if (cookies == null) return;
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
Cookie newCookie = new Cookie(name, null); // value 設為 null
newCookie.setPath("/");
newCookie.setMaxAge(0); // 立即刪除
response.addCookie(newCookie);
System.out.println("已刪除 Cookie: " + name);
break;
}
}
}
public class CookieUtils {
/**
* 根據名稱獲取 Cookie
*/
public static Cookie getCookieByName(HttpServletRequest request, String name) {
Map cookieMap = readCookieMap(request);
return cookieMap.get(name);
}
/**
* 將 Cookie 數組轉為 Map,便於 O(1) 查找
*/
private static Map readCookieMap(HttpServletRequest request) {
Map cookieMap = new HashMap<>();
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
cookieMap.put(cookie.getName(), cookie);
}
}
return cookieMap;
}
/**
* 獲取 Cookie 值,不存在返回默認值
*/
public static String getCookieValue(HttpServletRequest request, String name, String defaultValue) {
Cookie cookie = getCookieByName(request, name);
return cookie != null ? cookie.getValue() : defaultValue;
}
/**
* 添加 Cookie(靜態工具方法)
*/
public static void addCookie(HttpServletResponse response, String name, String value, int maxAgeSeconds, String path, String domain) {
Cookie cookie = new Cookie(name, value);
cookie.setMaxAge(maxAgeSeconds);
cookie.setPath(path);
if (domain != null) cookie.setDomain(domain);
response.addCookie(cookie);
}
/**
* 刪除 Cookie
*/
public static void removeCookie(HttpServletResponse response, String name, String path, String domain) {
Cookie cookie = new Cookie(name, null);
cookie.setMaxAge(0);
cookie.setPath(path);
if (domain != null) cookie.setDomain(domain);
response.addCookie(cookie);
}
}
name, path, domain 必須與創建時完全一致,否則瀏覽器視為不同 Cookie,導致操作失效。/ 使全站可見;若需隔離,需精確規劃路徑層級。cookie.setSecure(true) (僅 HTTPS 傳輸) 和 cookie.setHttpOnly(true) (防 XSS 竊取);Spring Boot 2.6+ 支持 SameSite 屬性(需反射或升級 Servlet API)。URLEncoder.encode(value, "UTF-8") 存儲,讀取時 URLDecoder.decode(value, "UTF-8")。封裝統一工具類,集中管理 Cookie 策略,能有效減少因屬性不一致導致的 Bug,提升開發效率。