1. 概述

HTTP Cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。

浏览器存储cookie,并将它们与下一个请求一起发送回同一服务器。

Cookies通常用于会话管理,用户跟踪以及存储用户首选项。

在本文中,我们将学习如何在Spring MVC中读取HTTP cookie。

2. 读取HTTP cookies

在Spring MVC中可以使用@CookieValue读取Cookies,当然我们也可以使用HttpServletResponse获取所有的Cookies。

2.1 @CookieValue

@CookieValue的属性和@RequestHeader基本一样。我们这里就简单的过一遍。

2.1.1 使用@CookieValue

@CookieValue注释可以获取任何HTTP cookie的值,而无需遍历从请求中获取的所有cookie。

比如:

@GetMapping("/")
@ResponseBody
public String readCookie(@CookieValue(value = "username") String username) {
  return "readCookie: username: " + username;
}

我们来测试一下:

  • 请求不带Cookies
# curl  http://localhost:8080/cookies/
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 400 Missing cookie &apos;username&apos; for method parameter of type String</title>
</head>
<body><h2>HTTP ERROR 400 Missing cookie &apos;username&apos; for method parameter of type String</h2>
<table>
<tr><th>URI:</th><td>/cookies/</td></tr>
<tr><th>STATUS:</th><td>400</td></tr>
<tr><th>MESSAGE:</th><td>Missing cookie &apos;username&apos; for method parameter of type String</td></tr>
<tr><th>SERVLET:</th><td>mvc</td></tr>
</table>
<hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.24.v20191120</a><hr/>

</body>
</html>
  • 请求带Cookies
# curl  --cookie "username=test" http://localhost:8080/cookies/
readCookie? username? test%

当指定参数的名称时,默认情况下参数是必需的。

如果没有对应的Cookies就会抛出java.lang.IllegalStateException异常 。

2.1.2 设置为可选参数

将Cookies参数设置为可选有三种方式。

  • 将required设置为False
@GetMapping("/op1")
@ResponseBody
public String readCookie1(@CookieValue(value = "username", required = false) String username) {
  return "readCookie: username: " + username;
}

测试一下:

# curl  http://localhost:8080/cookies/op1
readCookie: username: null%
  • 将参数包装在Optional类中
@GetMapping("/op2")
@ResponseBody
public String readCookie2(@CookieValue(value = "username") Optional<String> username) {
  return "readCookie: username: " + username.orElse("not set");
}

测试一下:

# curl  http://localhost:8080/cookies/op2
readCookie: username: not set%                                                                                           # curl --cookie "username=test"  http://localhost:8080/cookies/op2
readCookie: username: test%
  • 使用默认值
@GetMapping("/df")
@ResponseBody
public String readCookie3(@CookieValue(value = "username", defaultValue = "test") String username) {
return "readCookie: username: " + username;
}

测试一下

# curl  http://localhost:8080/cookies/df
readCookie: username: test%

# curl  --cookie "username=test2" http://localhost:8080/cookies/df
readCookie: username: test2%

2.2 使用HttpServletRequest读取所有Cookies

除了使用@CookieValue注释,我们还可以使用HttpServletRequest作为控制器方法参数来读取所有cookie。

HttpServletRequest提供了getCookies()方法,该方法以数组形式返回浏览器发送的所有cookie Cookie

@GetMapping("/all")
@ResponseBody
public String readAllCookies(HttpServletRequest request) {
  Cookie[] cookies = request.getCookies();
  if (cookies != null) {
    return Arrays.stream(cookies)
      .map(c -> c.getName() + "=" + c.getValue()).collect(Collectors.joining(", "));
  }
  return "No cookies";
}

我们来测试一下

# curl  --cookie "username=test2;test=test2" http://localhost:8080/cookies/all
username=test2, test=test2%

3. 结论

在本文中,我们学习在Spring MVC中通过@CookieValue以及使用HttpServletRequest来读取HTTP cookie。

与往常一样,可以在GitHub上找到示例代码。