HttpMessageConverter란?

김현정·2025년 4월 15일
1

HTTP 메세지 바디의 데이터 처리를 담당하는 HttpMessageConverter

HTTP 메세지 바디에서 데이터를 직접 읽어와야 하거나, 전달해야 할 때 사용되는 HTTP 메세지컨버터의 동작 원리를 나타낸다.

HTTP 메세지 컨버터는 HTTP API처럼 HTTP 메세지 바디에서 데이터를 직접 읽어와야 하거나, 전달해야 할 때 동작한다. 뷰 템플릿으로 HTML을 생성해서 응답하는 경우는 동작하지 않는다.


@ResponseBody가 동작하는 과정

  • HTTP의 BODY에 문자 내용을 직접 반환
  • viewResolver 대신에 HttpMessageConverter가 동작
  • 기본 문자처리: StringHttpMessageConverter
  • 기본 객체처리: MappingJackson2HttpMessageConverter
  • byte 처리 등등 기타 여러 HttpMessageConverter가 기본으로 등록되어 있음

응답의 경우 클라이언트의 HTTP Accept 헤더와 서버의 컨트롤러 반환 타입 정보를 조합해서 HttpMessageConverter가 선택된다.

  • HTTP 요청: @RequestBody, HttpEntity(RequestEntity)
  • HTTP 응답: @ResponseBody, HttpEntity(ResponseEntity)
    -> HttpMessageConverter는 요청과 응답 모두 사용된다.

HTTP 메시지 컨버터 인터페이스

package org.springframework.http.converter;
    public interface HttpMessageConverter<T> {

      boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
      boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

      List<MediaType> getSupportedMediaTypes();

      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() 메서드로 Class, MediaType 지원여부를 체크한다.
  • read(), write() 메서드로 HttpMessage 를 읽고 쓴다.

HttpMessageConverter의 우선순위

Spring은 다양한 HttpMessageConverter를 제공하고 있고 우선순위가 있다. 대상 Class와 MediaType을 체크해서 어떤 Converter를 사용할지 결정한다.

  1. ByteArrayHttpMessageConverter
    • byte[] Data를 처리한다.
    • 대상 : byte[]
    • MediaType : */*
    • 반환 : application/octet-stream
  2. StringHttpMessageConverter
    • String Data를 처리한다.
    • 대상 : String
    • MediaType : */*
    • 반환 : text/plain
  3. MappingJackson2HttpMessageConverter
    • JSON Data를 처리한다.
    • 대상 : Object, HashMap
    • MediaType : application/json
    • 반환 : application/json
  4. 기타
  • 이외에도 기본적으로 제공되는 다양한 MessageConverter가 존재한다.
  • 대부분의 경우 위 세 가지로 해결이 된다.

동작 순서

요청 데이터 읽기

  1. HTTP 요청이 오고, 컨트롤러에서 @RequestBody, HttpEntity 파라미터를 사용한다.
  2. 메세지 컨버터가 메세지를 읽을 수 있는지 확인하기 위해 canRead()를 호출한다.
    • 대상 클래스 타입을 지원하는가? @RequestBody의 대상 클래스 (byte[], String, HelloData)
    • HTTP 요청의 Content-Type(미디어 타입)을 지원하는가? text/plain, pplication/json, /
  3. canRead() 조건을 만족하면 read()를 호출해서 객체 생성하고, 반환한다.

응답 데이터 쓰기

  1. 컨트롤러에서 @ResponseBody, HttpEntity로 값이 반환된다.
  2. 메세지 컨버터가 메세지를 쓸 수 있는지 확인하기 위해서 canWrite()메서드를 호출한다.
    • 대상 클래스 타입을 지원하는가? return의 대상 클래스 (byte[], String, HelloData)
    • HTTP 요청의 Accept 미디어 타입을 지원하는가? (@RequestMapping의 produces를 의미한다) text/plain, application/json, /
  3. canWrite()조건을 만족하면 write()를 호출해서 HTTP 응답 메시지 바디에 데이터를 생성한다.

Controller에 produces 속성을 따로 설정하지 않으면 요청 헤더의 Accept가 Default 이다.

0개의 댓글