1.读取HTTP headers

1.1 单个读取

如果需要访问特定的标头,则可以使用标头名称配置@RequestHeader:

@GetMapping("/greeting")
public ResponseEntity<String> greeting(@RequestHeader("accept-language") String language) {
    // code that uses the language variable
    return new ResponseEntity<String>(greeting, HttpStatus.OK);
}

然后,我们可以使用传递到方法中的变量访问值。如果在请求中找不到名为accept-language的标头,则该方法将返回“ 400 Bad Request”错误。

我们的标题不必是字符串。例如,如果我们知道标题是数字,则可以将变量声明为数字类型:

@GetMapping("/double")
public ResponseEntity<String> doubleNumber(@RequestHeader("my-number") int myNumber) {
    return new ResponseEntity<String>(String.format("%d * 2 = %d", 
      myNumber, (myNumber * 2)), HttpStatus.OK);
}

1.2 全部读取

如果我们不确定会出现哪些标题,或者我们需要的标题多于方法签名中的标题,则可以使用@RequestHeader批注而不使用特定名称。

对于变量类型,我们有几种选择:Map,MultiValueMap或HttpHeaders对象。

首先,让我们以Map作为请求标头:

@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>(
      String.format("Listed %d headers", headers.size()), HttpStatus.OK);
}

如果我们使用Map并且其中一个标头具有一个以上的值,我们将只得到第一个值。这等效于在MultiValueMap上使用getFirst方法。

如果我们的标头可能有多个值,我们可以将它们作为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>(
      String.format("Listed %d headers", headers.size()), HttpStatus.OK);
}

我们还可以将标题作为HttpHeaders对象获取:

@GetMapping("/getBaseUrl")
public ResponseEntity<String> getBaseUrl(@RequestHeader HttpHeaders headers) {
    InetSocketAddress host = headers.getHost();
    String url = "http://" + host.getHostName() + ":" + host.getPort();
    return new ResponseEntity<String>(String.format("Base URL = %s", url), HttpStatus.OK);
}

HttpHeaders对象具有普遍的应用头文件存取。

当我们从Map,MultiValueMap或HttpHeaders对象中按名称访问标头时,如果不存在则为空。

2. @RequestHeader属性

现在,我们已经了解了使用@RequestHeader批注访问请求标头的基础知识,让我们仔细看一下其属性。

当我们专门命名标题时,我们已经隐式使用了namevalue属性:

public ResponseEntity<String> greeting(@RequestHeader("accept-language") String language) {}

我们可以使用name属性完成相同的事情:

public ResponseEntity<String> greeting(
  @RequestHeader(name = "accept-language") String language) {}

接下来,让我们以完全相同的方式使用value属性:

public ResponseEntity<String> greeting(
  @RequestHeader(value = "accept-language") String language) {}

当我们专门命名标题时,默认情况下标题是必需的。如果在请求中找不到标头,则控制器返回400错误。

让我们使用required属性来指示不需要我们的标头:

@GetMapping("/nonRequiredHeader")
public ResponseEntity<String> evaluateNonRequiredHeader(
  @RequestHeader(value = "optional-header", required = false) String optionalHeader) {
    return new ResponseEntity<String>(String.format(
      "Was the optional header present? %s!",
        (optionalHeader == null ? "No" : "Yes")),HttpStatus.OK);
}

由于如果请求中不存在标头,我们的变量将为null,因此我们需要确保进行适当的null检查。

让我们使用defaultValue属性为标头提供默认值:

@GetMapping("/default")
public ResponseEntity<String> evaluateDefaultHeaderValue(
  @RequestHeader(value = "optional-header", defaultValue = "3600") int optionalHeader) {
    return new ResponseEntity<String>(
      String.format("Optional Header is %d", optionalHeader), HttpStatus.OK);
}

参考:

https://www.baeldung.com/spring-rest-http-headers


🍎QQ群【837324215】
🍎关注我的公众号【Java大厂面试官】,一起学习呗🍎🍎🍎

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐