1. 概述

本文介绍如何在 Spring REST 控制器中获取 HTTP 请求头(HTTP Headers)。

我们将重点讲解使用 @RequestHeader 注解来分别获取单个 Header 或全部 Headers。

此外,我们还会深入探讨 @RequestHeader 的各个属性,包括 requireddefaultValue 的使用技巧。

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 不存在,从 MapMultiValueMapHttpHeaders 获取时会返回 null

3. @RequestHeader 属性详解

3.1. name / value 属性

我们可以使用 namevalue 属性来指定 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
  • ✅ 使用 MapMultiValueMapHttpHeaders 获取全部 Header
  • ✅ 使用 required = false 表示 Header 可选
  • ✅ 使用 defaultValue 设置默认值避免 null

这些技巧在实际开发中非常实用,尤其在处理请求认证、自定义参数、多语言支持等场景中,能大幅提升代码的可读性和健壮性。


原始标题:How to Read HTTP Headers in Spring REST Controllers | Baeldung