1. 概述
本文介绍如何在 Spring REST 控制器中获取 HTTP 请求头(HTTP Headers)。
我们将重点讲解使用 @RequestHeader
注解来分别获取单个 Header 或全部 Headers。
此外,我们还会深入探讨 @RequestHeader
的各个属性,包括 required
和 defaultValue
的使用技巧。
2. 获取 HTTP Headers
2.1. 分别获取单个 Header
如果你只需要获取某个特定的请求头,可以使用 @RequestHeader
注解并指定 Header 名称:
@GetMapping("/greeting")
public ResponseEntity<String> greeting(@RequestHeader(HttpHeaders.ACCEPT_LANGUAGE) String language) {
// 使用 language 变量执行逻辑
return new ResponseEntity<>(greeting, HttpStatus.OK);
}
如果请求中没有 accept-language
这个 Header,默认会返回 400 错误。
⚠️ 如果你确定 Header 的值是数字,可以直接声明为 int
类型,Spring 会自动转换:
@GetMapping("/double")
public ResponseEntity<String> doubleNumber(@RequestHeader("my-number") int myNumber) {
return new ResponseEntity<>(String.format("%d * 2 = %d", myNumber, (myNumber * 2)), HttpStatus.OK);
}
2.2. 一次性获取所有 Headers
如果你不确定请求中会包含哪些 Headers,或者不希望方法参数列表太长,可以使用 @RequestHeader
不指定名称,直接获取所有 Headers。
你可以选择使用以下几种类型接收:
Map<String, String>
MultiValueMap<String, String>
HttpHeaders
✅ 使用 Map 接收(只获取每个 Header 的第一个值):
@GetMapping("/listHeaders")
public ResponseEntity<String> listAllHeaders(@RequestHeader Map<String, String> headers) {
headers.forEach((key, value) -> {
LOG.info(String.format("Header '%s' = %s", key, value));
});
return new ResponseEntity<>(String.format("Listed %d headers", headers.size()), HttpStatus.OK);
}
✅ 使用 MultiValueMap 接收(可以获取多个值):
@GetMapping("/multiValue")
public ResponseEntity<String> multiValue(@RequestHeader MultiValueMap<String, String> headers) {
headers.forEach((key, value) -> {
LOG.info(String.format("Header '%s' = %s", key, value.stream().collect(Collectors.joining("|"))));
});
return new ResponseEntity<>(String.format("Listed %d headers", headers.size()), HttpStatus.OK);
}
✅ 使用 HttpHeaders 接收(用于获取 Host 等标准 Header):
@GetMapping("/getBaseUrl")
public ResponseEntity<String> getBaseUrl(@RequestHeader HttpHeaders headers) {
InetSocketAddress host = headers.getHost();
String url = "http://" + host.getHostName() + ":" + host.getPort();
return new ResponseEntity<>(String.format("Base URL = %s", url), HttpStatus.OK);
}
⚠️ 注意:如果指定的 Header 不存在,从 Map
、MultiValueMap
或 HttpHeaders
获取时会返回 null
。
3. @RequestHeader 属性详解
3.1. name / value 属性
我们可以使用 name
或 value
属性来指定 Header 名称。以下三种写法是等效的:
public ResponseEntity<String> greeting(@RequestHeader(HttpHeaders.ACCEPT_LANGUAGE) String language) {}
public ResponseEntity<String> greeting(@RequestHeader(name = HttpHeaders.ACCEPT_LANGUAGE) String language) {}
public ResponseEntity<String> greeting(@RequestHeader(value = HttpHeaders.ACCEPT_LANGUAGE) String language) {}
3.2. required 属性
默认情况下,Header 是必须的。如果请求中没有该 Header,Spring 会抛出异常并返回 400。
可以通过 required = false
设置为可选:
@GetMapping("/nonRequiredHeader")
public ResponseEntity<String> evaluateNonRequiredHeader(
@RequestHeader(value = "optional-header", required = false) String optionalHeader) {
return new ResponseEntity<>(String.format(
"Was the optional header present? %s!", (optionalHeader == null ? "No" : "Yes")), HttpStatus.OK);
}
⚠️ 此时 optionalHeader
可能为 null
,需要手动判断。
3.3. defaultValue 属性
为可选 Header 设置默认值,避免 null
判断:
@GetMapping("/default")
public ResponseEntity<String> evaluateDefaultHeaderValue(
@RequestHeader(value = "optional-header", defaultValue = "3600") int optionalHeader) {
return new ResponseEntity<>(String.format("Optional Header is %d", optionalHeader), HttpStatus.OK);
}
这样即使请求中没有该 Header,也会使用默认值 3600。
4. 小结
本文介绍了如何在 Spring REST 控制器中读取 HTTP 请求头:
- ✅ 使用
@RequestHeader("headerName")
获取单个 Header - ✅ 使用
Map
、MultiValueMap
或HttpHeaders
获取全部 Header - ✅ 使用
required = false
表示 Header 可选 - ✅ 使用
defaultValue
设置默认值避免null
这些技巧在实际开发中非常实用,尤其在处理请求认证、自定义参数、多语言支持等场景中,能大幅提升代码的可读性和健壮性。