@CookieValue
注解的作用
@CookieValue
注解用于将 HTTP 请求中特定 Cookie 的值绑定到 Controller 方法的参数上。
Cookies 是由服务器发送到用户浏览器并保存在本地的一小块数据。浏览器在后续向同一服务器发送请求时,会通过 Cookie
请求头将这些数据再带回给服务器。Cookies 常用于:
- 会话管理(如存储会话 ID)
- 用户偏好设置(如主题、语言)
- 跟踪用户行为
@CookieValue
提供了一种方便的方式来直接在 Controller 方法中访问这些 Cookie 的值,而无需手动解析 HttpServletRequest
中的 Cookie
头或 getCookies()
数组。
基本用法
需要指定要读取的 Cookie 的名称,并将带有 @CookieValue
注解的参数声明为相应类型(通常是 String
)。
java
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")
@ResponseBody
public String showSessionId(@CookieValue("sessionId") String sessionId) {
// 此时,如果请求中包含名为 "sessionId" 的 Cookie,
// 其值会被自动赋给方法参数 sessionId
return "Session ID from cookie is: " + sessionId;
}
// 读取名为 "user-preference" 的 Cookie 的值
@GetMapping("/show-preference")
@ResponseBody
public 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
java
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 可选,如果不存在则使用默认值
java
@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
。
java
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
)。