티스토리 뷰
스프링부트로 API 서버를 구축할 때, 우리는 자연스럽게 HTTP 메시지 컨버터를 사용한다.
@RequestBody, @ResponseBody를 사용하게 되면 viewResolver 대신 HttpMessageConverter가 동작되는데, 이 HttpMessageConverter에 대해 정리하고자 한다.
스프링 MVC는 다음의 경우에 HTTP 메시지 컨버터를 사용한다.
- HTTP 요청: @RequestBody, HttpEntity(RequestEntity)
- HTTP 응답: @ResponseBody, HttpEntity(ResponseEntity)
HTTP 메시지 컨버터 인터페이스 코드를 살펴보면 아래와 같다.
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
List<MediaType> getSupportedMediaTypes();
default List<MediaType> getSupportedMediaTypes(Class<?> clazz) {
return (canRead(clazz, null) || canWrite(clazz, null) ?
getSupportedMediaTypes() : Collections.emptyList());
}
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
}
메소드 명을 보면 대충 짐작이 갈 것이다.
canRead(), canWrite() 메소드를 사용하여 메시지 컨버터가 해당 클래스, 미디어타입을 지원하는지 체크한다.
그 이후에 read(), wirte() 메소드를 사용하여 메시지를 읽고 쓴다.
스프링부트는 다양한 메시지 컨버터를 제공하는데, 주로 사용하는 메시지 컨버터 우선순위는 아래와 같다
- ByteArrayHttpMessageConverter
- StringHttpMessageConverter
- MappingJackson2HttpMessageConverter
대상 클래스 타입과 미디어 타입 둘을 체크하여 우선순위 순서대로 해당 메시지 컨버터 사용여부를 결정한다.
해당 메시지 컨버터를 간단하게 정리하자면
- ByteArrayHttpMessageConverter: byte[] 데이터 처리
- 클래스 타입: byte[], 미디어타입: */*
- StringHttpMessageConverter: String 문자로 데이터 처리
- 클래스 타입: String, 미디어타입: */*
- MappingJackson2HttpMessageConverter: application/json
- 클래스 타입: 객체 또는 HashMap, 미디어타입: application/json
*요약
HTTP 요청 데이터 읽기
- HTTP 요청이 오고, 컨트롤러에서 @RequestBody , HttpEntity 파라미터를 사용한다.
- 메시지 컨버터가 메시지를 읽을 수 있는지 확인하기 위해 canRead() 를 호출한다.
- 대상 클래스 타입을 지원하는가? 예) @RequestBody 의 대상 클래스 ( byte[] , String , HelloData )
- HTTP 요청의 Content-Type 미디어 타입을 지원하는가? 예) text/plain, application/json, */*
- canRead() 조건을 만족하면 read() 를 호출해서 객체 생성하고, 반환한다.
HTTP 응답 데이터 생성
- 컨트롤러에서 @ResponseBody , HttpEntity 로 값이 반환된다.
- 메시지 컨버터가 메시지를 쓸 수 있는지 확인하기 위해 canWrite() 를 호출한다.
- 대상 클래스 타입을 지원하는가? 예) return의 대상 클래스 ( byte[] , String , HelloData )
- HTTP 요청의 Accept 미디어 타입을 지원하는가? 예) text/plain, application/json, */*
- canWrite() 조건을 만족하면 write() 를 호출해서 HTTP 응답 메시지 바디에 데이터를 생성한다.
참고) 스프링 MVC - 백엔드 웹 개발 핵심 기술(김영한)