자바 개발자를 위한 온라인 리소스 및 교육 플랫폼 중 "Baeldung" 내에서 제공하는 REST API 관련 Tutorial에 대해 학습해보는 시간을 갖겠습니다.
해당 내용은 전적으로 Baeldung에 기재된 내용을 바탕으로 서술되어 있으며, 관련 내용 중 필자가 부족한 개념은 추가로 포스팅할 예정입니다.
📜 참고글
이번 포스팅에서는 Spring Rest Controller에서 HTTP 헤더에 접근하기 위한 방법에 대해서 학습하겠습니다.
@GetMapping("/greeting")
public ResponseEntity<String> greeting(@RequestHeader(HttpHeaders.ACCEPT_LANGUAGE) String language) {
// code that uses the language variable
return new ResponseEntity<String>(greeting, HttpStatus.OK);
}
특정 header에 접근하기 위해서는 @RequestHeader 어노테이션을 사용하여 header명을 통해서 접근이 가능합니다.
만약, HTTP Request Header에 해당 header명 값이 있을 경우, 해당 값에 접근할 수 있으며, 없을 경우 400(Bad Request) 오류를 반환합니다.
그리고 특정 header 값이 반드시 String일 필요는 없습니다. 만약, header 값이 숫자형(Numeric) 인 것을 아는 경우에, 해당 타입으로 값을 받아주면 됩니다.
@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);
}
만약 어떤 header가 존재하는지 특정하기 어려운 경우, @RequestHeader 어노테이션에 header명을 추가하지 않고 전체 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>(
String.format("Listed %d headers", headers.size()), HttpStatus.OK);
}
Map으로 반환 받을 경우, header 내 하나 이상의 값을 포함하고 있더라도 first value 하나를 반환받게 됩니다.
만약, headers에 여러 값을 포함하고 있는 경우에는 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 객체로 headers에 접근 가능합니다.
@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는 공통적인 application headers에 접근 가능합니다.
만약, 특정 header의 값이 존재하지 않을 경우, null을 반환합니다.
public ResponseEntity<String> greeting(
@RequestHeader(name = HttpHeaders.ACCEPT_LANGUAGE) String language) {}
public ResponseEntity<String> greeting(
@RequestHeader(value = HttpHeaders.ACCEPT_LANGUAGE) String language) {}
위에서 언급한 바로는 특정 name(value)로 접근하려 했던 header가 요청 headers에 존재하지 않은 경우 400(Bad Request)를 반환 및 응답한다고 말했습니다.
하지만, 이는 required 속성이 true로 기본 설정되어 있기 때문입니다. 이를 false로 명시해주면, header가 존재하지 않을 경우, null을 반환합니다.
@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);
}
만약, header가 존재하지 않을 떄, 변수에 담을 default 값을 설정하고 싶은 경우 이를 설정할 수 있습니다.
@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);
}
이번 포스팅에서는 REST Controller에서 HTTP Header에 접근하는 방법에 대해서 학습했습니다.
단일 접근 시 @RequestHeader와 name 속성을 통해서 접근 가능하며, 해당 값이 존재하지 않을 경우를 대비한 속성들에 대해서도 알아봤습니다.
또한, 여러 header에 한번에 접근하기 위한 방법도 함께 알아봤습니다.