Spring REST 컨트롤러에서 HTTP 헤더 읽기
Spring 컨트롤러에서 HTTP 헤더를 읽는 방법을 소개한다.
- @RequestHeader annotation
- HttpServletRequest 인스턴스
@RequestHeader annotation
Spring은 전체 또는 특정 헤더 값을 컨트롤러 메서드의 인수로 맵핑하는 @RequestHeader annotation을 제공한다.
@RequestHeader annotation 유형은 파라미터이다.
HashMap을 통한 HTTP 헤더 읽기
@RequestHeader annotation을 사용해 모든 HTTP 헤더를 Map 인스턴스에 맵핑한다.
@PostMapping(value = "/read-header-map")
public void readHeader(@RequestHeader Map<String, String>headers) {
log.info("headers: {}", headers);
}
headers: {content-type=application/json, user-agent=PostmanRuntime/7.34.0, accept=*/*, host=localhost:8080, accept-encoding=gzip, deflate, br, connection=keep-alive, content-length=43}
HTTPHeaders 인스턴스를 통한 HTTP 헤더 읽기
HttpHeaders 인스턴스에 헤더 정보를 주입할 수도 있다.
HttpHeaders는 MultiValueMap 클래스의 구현체이다.
public class HttpHeaders implements MultiValueMap<String, String>, Serializable {...}
@PostMapping(value = "/read-header-http-headers")
public void readHeaderHttpHeaders(@RequestHeader HttpHeaders httpHeaders) {
log.info("headers: {}", httpHeaders);
}
headers: [content-type:"application/json", user-agent:"PostmanRuntime/7.34.0", accept:"*/*", host:"localhost:8080", accept-encoding:"gzip, deflate, br", connection:"keep-alive", content-length:"43"]
HttpHeaders가 MultiValueMap 클래스의 구현체이므로 MultiValueMap 타입으로도 헤더 정보를 주입받을 수 있다.
MultiValueMap은 동일 키에 대해서 List 타입의 Value를 저장한다.
public interface MultiValueMap<K, V> extends Map<K, List<V>>{...}
@PostMapping(value = "/read-header-multi-value-map")
public void readHeaderMultiValueMap(@RequestHeader MultiValueMap<String, String> httpHeaders) {
log.info("headers: {}", httpHeaders);
}
headers: {content-type=[application/json], user-agent=[PostmanRuntime/7.34.0], accept=[*/*], host=[localhost:8080], accept-encoding=[gzip, deflate, br], connection=[keep-alive], content-length=[43]}
특정 HTTP 헤더 읽기
@RequestHeader를 사용하여 특정 헤더 필드만 읽을 수 있다.
@PostMapping(value = "/read-header-specific")
public void readHeaderSpecific(@RequestHeader("user-agent") String userAgent) {
log.info("user-agent: {}", userAgent);
}
user-agent: PostmanRuntime/7.34.0
@RequestHeader에 지정되는 필드명은 대소문자 구분을 하지 않는다.
@RequestHeader에 지정된 헤더 필드는 Spring에서 필수 헤더로 취급한다.
@RequestHeader에 지정된 헤더 필드가 요청 헤더에 존재하지 않으면 Spring은 400(Bad Request)를 응답한다.
지정된 헤더 필드를 optional 하게 만들기 위해서는 다음과 같이 사용한다.
@PostMapping(value = "/read-header-specific")
public void readHeaderSpecific(
@RequestHeader(
value = "optional-header",
required = false,
defaultValue = "") String optionalHeader) {
log.info("optional-header: {}", optionalHeader);
}
@RequestHeader에 지정된 헤더 필드가 요청 헤더가 없는 경우에는 헤더 필드 파라미터는 defaultValue에 지정된 값이 할당된다.
defaultValue 속성이 지정된 경우 required 속성과 관계없이 지정된 헤더 필드가 요청 헤더에 없거나 Null 인 경우 defaultValue 속성에 지정된 값을 파라미터에 주입한다.
HttpServletRequest를 통한 HTTP 헤더 읽기
HttpServletRequest 인스턴스를 통해서 직접 요청 헤더 값을 읽을 수 있다.
@PostMapping(value = "/read-header-servlet-request")
public void readHeaderHttpServletRequest(HttpServletRequest request) {
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
log.info("{} : {}", headerName, request.getHeader(headerName));
}
}
user-agent : PostmanRuntime/7.34.0
accept : */*
content-type : application/json
host : localhost:8080
accept-encoding : gzip, deflate, br
connection : keep-alive
content-length : 43