@CookieValue
注解的作用
@CookieValue
注解用于將 HTTP 請求中特定 Cookie 的值綁定到 Controller 方法的參數上。
Cookies 是由服務器發送到用戶瀏覽器并保存在本地的一小塊數據。瀏覽器在后續向同一服務器發送請求時,會通過 Cookie
請求頭將這些數據再帶回給服務器。Cookies 常用于:
- 會話管理(如存儲會話 ID)
- 用戶偏好設置(如主題、語言)
- 跟蹤用戶行為
@CookieValue
提供了一種方便的方式來直接在 Controller 方法中訪問這些 Cookie 的值,而無需手動解析 HttpServletRequest
中的 Cookie
頭或 getCookies()
數組。
基本用法
需要指定要讀取的 Cookie 的名稱,并將帶有 @CookieValue
注解的參數聲明為相應類型(通常是 String
)。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class CookieDemoController {// 讀取名為 "sessionId" 的 Cookie 的值@GetMapping("/show-session-id")@ResponseBodypublic String showSessionId(@CookieValue("sessionId") String sessionId) {// 此時,如果請求中包含名為 "sessionId" 的 Cookie,// 其值會被自動賦給方法參數 sessionIdreturn "Session ID from cookie is: " + sessionId;}// 讀取名為 "user-preference" 的 Cookie 的值@GetMapping("/show-preference")@ResponseBodypublic String showUserPreference(@CookieValue("user-preference") String preference) {return "User preference from cookie: " + preference;}
}
重要:
- 與
@RequestHeader
類似,name
(或value
) 屬性是必需的,用來指定要讀取的 Cookie 的名稱。因為方法參數名通常與 Cookie 名稱不直接對應。
@CookieValue
的屬性
@CookieValue
提供了一些屬性來控制綁定行為:
-
name
(或value
):- 必需屬性。指定要綁定的 Cookie 的名稱。
name
和value
是同義詞。- 示例:
@CookieValue(name = "visitorId") String visitorId
。
-
required
:- 指定該 Cookie 是否必須存在于請求中。
- 類型:
boolean
。 - 默認值:
true
。如果required=true
,但請求中沒有該名稱的 Cookie,Spring MVC 會拋出MissingRequestCookieException
異常,導致 HTTP 400 (Bad Request) 響應。 - 如果 Cookie 是可選的,需要設置為
required = false
。
-
defaultValue
:- 當請求中沒有提供該 Cookie 時,為其提供一個默認值。
- 類型:
String
。 - 注意: 使用
defaultValue
隱含了required = false
的行為。提供了defaultValue
后,即使不顯式設置required = false
,該 Cookie 也不再是必需的。如果 Cookie 不存在,就會使用默認值,不會拋出異常。
處理可選 Cookie 和默認值
場景 1:Cookie 可選,如果不存在則為 null
import java.util.Optional;
// ...@GetMapping("/optional-cookie-demo")
@ResponseBody
public String processOptionalCookie(@CookieValue(name = "trackingId", required = false) String trackingId,@CookieValue(name = "abTestGroup", required = false) Optional<String> group) {String trackingMessage = (trackingId != null) ? "Tracking ID: " + trackingId : "Tracking ID cookie is missing";String groupMessage;if (group.isPresent()) {groupMessage = "A/B Test Group: " + group.get();} else {groupMessage = "A/B Test Group cookie is missing";}return trackingMessage + "\n" + groupMessage;
}
- 使用
required = false
,如果 Cookie 不存在,對應的String
參數會是null
。 - 使用
Optional<String>
(Spring 4.1+) 是處理可選值的一種安全的方式。
場景 2:Cookie 可選,如果不存在則使用默認值
@GetMapping("/theme-setting")
@ResponseBody
public String getThemeSetting(// 如果請求中沒有名為 "appTheme" 的 Cookie,theme 參數的值將是 "light"@CookieValue(name = "appTheme", defaultValue = "light") String theme) {return "Current application theme (from cookie or default): " + theme;
}// 實踐: 顯式聲明 required=false 增加可讀性
@GetMapping("/language-setting")
@ResponseBody
public String getLanguageSetting(@CookieValue(name = "userLang", required = false, defaultValue = "en") String language) {return "User language (from cookie or default): " + language;
}
綁定到 javax.servlet.http.Cookie
對象
如果需要的不僅僅是 Cookie 的值,還想訪問 Cookie 的其他屬性(如 Path
, Domain
, MaxAge
, HttpOnly
等),我們可以直接將參數類型聲明為 javax.servlet.http.Cookie
。
import javax.servlet.http.Cookie;
// ...@GetMapping("/get-full-cookie")
@ResponseBody
public String getFullCookieObject(// 同樣需要設置 required = false 來處理 Cookie 不存在的情況@CookieValue(name = "fullCookieExample", required = false) Cookie fullCookie) {if (fullCookie != null) {String name = fullCookie.getName();String value = fullCookie.getValue();String path = fullCookie.getPath();int maxAge = fullCookie.getMaxAge();boolean httpOnly = fullCookie.isHttpOnly();return String.format("Cookie '%s': Value=%s, Path=%s, MaxAge=%d, HttpOnly=%b",name, value, path, maxAge, httpOnly);} else {return "Cookie 'fullCookieExample' not found.";}
}
當綁定到 Cookie
對象時,defaultValue
屬性不適用。只能通過 required = false
來處理 Cookie 不存在的情況(此時 fullCookie
參數將為 null
)。
總結
@CookieValue
用于將 HTTP 請求中指定名稱的 Cookie 的值綁定到方法參數。- 必須 使用
name
或value
屬性來指定 Cookie 名稱。 - 使用
required = false
使 Cookie 變為可選(不存在時參數為null
或Optional.empty()
)。 - 使用
defaultValue = "value"
為可選 Cookie 提供默認值(Cookie 不存在時生效,隱含required=false
)。 - 參數類型通常是
String
,但也可以直接綁定到javax.servlet.http.Cookie
對象以訪問 Cookie 的所有屬性(此時defaultValue
不可用,需用required=false
處理缺失情況)。 - 它是處理特定 Cookie 的便捷方式,用于區別處理查詢參數 (
@RequestParam
)、路徑變量 (@PathVariable
)、請求頭 (@RequestHeader
) 或請求體 (@RequestBody
)。