1. 概要

このクイックチュートリアルでは、 Spring RestControllerでHTTPヘッダーにアクセスする方法を見ていきます。

まず、 @RequestHeader アノテーションを使用して、ヘッダーを個別に、またはすべて一緒に読み取ります。

その後、@RequestHeader属性について詳しく見ていきます。

2. HTTPヘッダーへのアクセス

2.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 という名前のヘッダーがリクエストに見つからない場合、メソッドは「400BadRequest」エラーを返します。

ヘッダーは文字列である必要はありません。 ヘッダーが数値であることがわかっている場合は、変数を数値型として宣言できます。

@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);
}

2.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 を使用し、ヘッダーの1つに複数の値がある場合、は最初の値のみを取得します。これは、getFirstを使用するのと同じです。 ] MultiValueMapのメソッド。

ヘッダーに複数の値がある場合は、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 オブジェクトから名前でヘッダーにアクセスすると、nullがない場合に取得されます。存在しません。

3. @RequestHeader属性

@RequestHeader アノテーションを使用してリクエストヘッダーにアクセスする基本について説明したので、その属性を詳しく見ていきましょう。

ヘッダーに具体的に名前を付けた場合、nameまたはvalue属性を暗黙的に使用しました。

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);
}

4. 結論

この短いチュートリアルでは、SpringRESTコントローラーでリクエストヘッダーにアクセスする方法を学びました。

まず、 @RequestHeader アノテーションを使用して、コントローラーメソッドにリクエストヘッダーを提供しました。

基本を確認した後、@RequestHeaderアノテーションの属性を詳しく調べました。

サンプルコードは、GitHubから入手できます。