본문 바로가기
Spring(JAVA Framework)/Spring MVC

HTTP Message Converter

by 걸어가는 신사 2021. 9. 18.
HTTP API처럼 JSON 데이터를 HTTP Message Body에서 직접 읽거나 쓰는 경우 HTTP Message Converter를 동작한다. 

  • ViewResolver 대신에 HttpMessageConverter가 동작
  • 스프링 MVC는 다음의 경우에 HTTP Message Converter가 동작한다.
    • HTTP 요청 : @RequestBody, HttpEntity(RequestEntity)
    • HTTP 응답 : @ResonseBody, HttpEntity(ResponseEntity)

 

1.  HTTP Message Converter Interface

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;
}
  • HTTP Message Converter는 HTTP 요청, HTTP 응답 둘 다 사용된다.
    • canRead(), canWrite() : Message Converter가 해당 클래스, 미디어 타입을 지원하는지 체크
    • read(), write() : Message Converter를 통해서 메시지를 읽고 쓰는 기능

 

2. SpringBoot 기본 MessageConverter

0 = ByteArrayHttpMessageConverter
1 = StringHttpMessageConverter
2 = MappingJackson2HttpMessageConverter
(일부 생략)
SpringBoot는 다양한 Message Converter를 제공하는데, 대상 클래스 타입과 미디어 타입 둘을 체크해서 사용 여부를 결정. 만약 만족하지 않으면 다음 Message Converter로 우선순위가 넘어간다.
  • ByteArrayHttpMessageConverter : byte[] 데이터를 처리한다.
    • 클래스 타입 : byte[], 미디어 타입 : */*
    • 요청 ex) @RequestBody byte[] data
    • 응답 ex) @ResponseBody return byte[], 미디어 타입 : application/octet-stream
  • StringHttpMessageConverter : String 문자로 데이터를 처리한다.
    • 클래스 타입 : String, 미디어 타입 : */*
    • 요청 ex) @RequestBody String data
    • 응답 ex) @ResponseBody return "ok", 미디어 타입 : text/plain
  • MappingJackson2HttpMessageConverter : application/json
    • 클래스 타입 : 객체 또는 HashMap, 미디어 타입 : application/json
    • 요청 ex) @RequestBody HelloData data
    • 응답 ex) @ResponseBody retrun helloData, 미디어 타입 : appllication/json

 

3. Message Converter 동작 방식

(1) HTTP 요청 데이터 읽기

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

(2) HTTP 응답 데이터 생성

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

 

4. ReqeustMappingHandlerAdapter

HTTP Message Converter는 스프링 MVC 어디쯤에서 사용되는 것 일까?

(1) SpringMVC 구조

(2) RequestMappingHandlerAdapter

  • 컨트롤러의 파라미터, 어노테이션 사용 시 RequestMappingHandlerAdapter 호출된다.

(3) ArgumentResolver, ReturnValueHandler

  • ArgumentResolver
    • RequestMappingHandlerAdapter는 ArgumentResolver를 호출한다.
    • ArgumentResolver는 Controller(handler)가 필요로 하는 다양한 파라미터의 값(객체)을 생성한다.
    • 피라미터 값이 모두 준비되면 컨트롤러를 호출하면서 값을 넘겨준다.
    • 스프링은 30개가 넘는 ArgumentResolver를 기본으로 제공한다.
  • RetrunValueHandler
    • 응답 값을 변환하고 처리한다.
    • 컨트롤러에서 String으로 뷰 이름을 반환할 때 동작한다.
    • 스프링은 10여 개가 넘은 ReturnValueHandler를 지원한다.
      • ex) ModelAndView, @ResponseBody, HttpEntity, String

(4) HTTP Message Converter 위치

  • 요청
    • @RequestBody를 처리하는 ArgumentResolver가 있고, HttpEntity를 처리하는 ArgumentResolver가 있다.
    • 이 ArgumentResolver들이 HTTP Message Converter를 사용해서 필요한 객체를 생성한다.
  • 응답
    • @ResponseBody와 HttpEntity를 처리하는 ReturnValueHandler가 있다. 
    • 이 ReturnValueHandler들이 HTTP Message Converter를 호출해서 응답 결과를 만든다. 
반응형

'Spring(JAVA Framework) > Spring MVC' 카테고리의 다른 글

Thymeleaf 사용법  (0) 2021.09.19
HTTP Response  (0) 2021.09.18
HTTP Request - (2) (feat. Request Message Body)  (0) 2021.09.17
HTTP Request - (1) (feat. Request Parameter)  (0) 2021.09.16
@RequestMapping  (0) 2021.09.15

댓글