1. 소개

이 빠른 예제에서는 Spring Rest Controller 에서 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 라는 헤더 가 요청에 없으면 메서드는 "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);
}

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 을 사용 하고 헤더 중 하나에 둘 이상의 값 이 있으면 첫 번째 값만 얻습니다 . 이것은 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 객체 에서 이름으로 헤더에 액세스 할 때 존재하지 않으면 null을 얻습니다 .

3. @RequestHeader 속성

이제 @RequestHeader 어노테이션을 사용하여 요청 헤더에 액세스하는 기본 사항을 살펴 보았으므로 해당 속성을 자세히 살펴 보겠습니다.

헤더의 이름을 구체적으로 지정할 때 이미 이름 또는 속성을 암시 적으로 사용했습니다 .

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. 결론

이 짧은 예제에서는 Spring REST 컨트롤러에서 요청 헤더에 액세스하는 방법을 배웠습니다. 먼저 @RequestHeader 어노테이션을 사용하여 컨트롤러 메서드에 요청 헤더를 제공했습니다.

기본 사항을 살펴본 후 @RequestHeader 어노테이션 의 속성을 자세히 살펴 보았습니다 .

예제 코드는 GitHub에서 사용할 수 있습니다 .