[Spring] HttpMessageConveter에 대해서
HttpMessageConverter는 스프링 프레임워크에서 제공하는 인터페이스로 클라이언트가 서버에 JSON/XML 형식으로 이루어진 데이터를 보냈을 때 HttpMessageConverter가 동작해 적절한 Java Object로 변환하고 처리 결과에 대한 응답역시 Java Object를 다시 JSON/XML 형식으로 변환해주는 역할을 수행합니다.
스프링의 경우 다음의 경우에 HttpMessageConverter를 적용합니다.
- Http Request: @RequestBody, HttpEntity(ResponseEntity)
- Http Response: @ResponseBody, HttpEntity(ResponseEntity)
다양한 HttpMessageConverter의 구현체가 있으며 사용자가 어떤 형식의 요청을 보냈는지에 따라 사용되는 Converter도 달라집니다.
주로 사용하는 Converter는 아래와 같습니다.
- ByteArrayHttpMessageConverter
- StringHttpMessageConverter
- MappingJackson2HttpMessageConverter
| HttpMessageConverter 살펴보기
HttpMessageConverter는 다음과 같습니다.
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()는 Converter가 해당 클래스와 미디어 타입을 지원하는지 확인하는 용도이고 read()와 write()는 Converter를 통해 메시지를 읽고 쓰는 기능을 제공합니다.
스프링은 서버 구동시 기본으로 등록되는 Convereter가 있습니다.
대상 클래스와 미디어 타입을 체크해 사용 여부를 결정하고 조건에 만족하지 않는다면 다음 Converter로 넘어갑니다.
클라이언트가 요청을 보내면 요청 헤더의 Content-type
헤더의 미디어 타입을 읽어와 Converter가 해당 미디어 타입을 지원하는지를 여부를 확인하는 canRead() 메서드가 동작하고 지원하면 read() 메서드가 호출됩니다.
요청에 대한 결과를 클라이언트에게 반환할 때는 메시지를 작성할 수 있는지 확인하기 위해 canWrite() 메서드를 호출하고 요청 헤더의 Accept
헤더의 미디어 타입과 컨트롤러의 반환 타입을 조합해 적절한 Converter가 선택되고 write() 메서드를 호출해 객체를 생성합니다.
| HttpMessageConverter가 적용되는 시점
어노테이션 기반 컨트롤러는 HttpServletRequest, Model, @RequestParam, @ModelAttribute, @RequestBody, HttpEntity 등 다양한 파라미터를 사용할 수 있습니다. 이렇게 다양하게 처리해줄 수 있는 이유는 ArgumentResovler 때문입니다.
스프링은 HttpMessageConverter처럼 다양한 ArguementResolver 구현체가 있습니다.
컨트롤러를 처리하는 RequestMappingHandlerAdapter가 ArgumentResolver를 호출하면서 필요로 하는 다양한 파라미터 값을 HttpMessageConverter를 사용해 생성한 후 객체를 생성한 후 컨트롤러에게 넘겨줍니다. (1번, 2번 과정)
ReturnValueHandler는 응답 값을 변환하고 처리합니다. 해당 과정역시 요청과 마찬가지로 HttpMessageConverter를 사용해 응답 결과를 생성합니다.
즉, HttpMessageConverter는 ArgumentResolver와 ReturnValueHandler의 과정에서 이용합니다.
댓글남기기