-> 블로그 이전

[Spring] HTTP 메시지 컨버터

2022. 6. 12. 18:16Language`/Spring

뷰 템플릿으로 HTML을 생성해서 response하는게 아니라, HTTP API처럼 JSON형식의 데이터를 HTTP Message Body에 읽거나 쓸 경우 "HTTP 메시지 컨버터"를 사용하면 손쉽게 body의 데이터를 조작할 수 있다

  • JSON뿐만 아니라 Message Body의 내용을 HTTP 메시지 컨버터가 알아서 binding을 해준다

 

스프링 MVC의 경우 다음 경우에 HTTP 메시지 컨버터를 적용한다

<HTTP Request>
@RequestBody
HttpEntity(RequestEntity)

<HTTP Response>
@ResponseBody
HttpEntity(ResponseEntity)

 

HTTP 메시지 컨버터 Interface

HTTP 메시지 컨버터 Interface 내부 메소드에는 총 4가지가 존재한다

(1) canRead / canWrite

boolean canRead(class<?> clazz, @Nullabale MediaType mediaType);
boolean canWrite(class<?> clazz, @Nullabale MediaType mediaType);

이 메소드들은 일단 각 메시지 컨버터들이 "해당 클래스 & 미디어타입"을 지원하는지 check해주는 메소드이다

 

여기서 통과를 하게 되면  다음 메소드를 실행한다

(2) read / write

T read(Class<? extends T> clazz, HttpInputMessage inputMessage) 
		throws IOException, HttpMessageNotReadableException;
        
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
		throws IOException, HttpMessageNotWritableException;

(1) 단계에서 선택된 메시지 컨버터를 통해서 메시지를 읽고 쓰는 메소드이다

 

 

메시지 컨버터 종류

스프링에서 제공해주는 수많은 컨버터들 중에서 대표적인 메시지 컨버터는 다음 종류들이 있다

0순위 : ByteArrayHttpMessageConver

이 메시지 컨버터는 "byte [] 데이터"를 처리해주는 컨버터이다

  • 클래스 타입 : byte []
  • 미디어 타입 : */*
  • Request Example : @RequestBody byte [] data
  • Response Example : @ResponseBody return byte [] & 미디어타입 = application/octet-stream

 

1순위 : StringHttpMessageConverter

이 메시지 컨버터는 "String 문자 데이터"를 처리해주는 컨버터이다

  • 클래스 타입 : String
  • 미디어 타입 : */*
  • Request Example : @RequestBody String data
  • Response Example : @ResponseBody return "ok" & 미디어타입 = text/plain

 

2순위 : MappingJackson2HttpMessageConverter

이 메시지 컨버터는 "JSON 데이터"를 처리해주는 컨버터이다

  • 클래스 타입 : 객체 or HashMap
  • 미디어 타입 : application/json 관련
  • Request Example : @RequestBody HelloData data
  • Response Example : @ResponseBody return data & 미디어타입 = application/json 관련

 

content-type: application/json

@RequestMapping
void hello(@RequestBody String data){}

일단 클래스 타입부터 보면 @RequestBody뒤에 String이 보이므로 "StringHttpMessageConverter"가 후보군으로 올라왔다

그리고 미디어타입을 보면 application/json이다

>> "StringHttpMessageConverter"가 {클래스 & 미디어타입} 둘다 지원하므로 이 경우 StringHttpMessageConverter를 통해서 body의 메시지를 읽을 수 있다

 

content-type: application/json

@RequestMapping
void hello(@RequestBody HelloData data){}

이 경우 {클래스 & 미디어 타입}을 고려했을 때 "MappingJackson2HttpMessageConverter"를 통해서 바디에 존재하는 JSON 데이터를 읽을 수 있다

 

content-type: text/html

@RequestMapping
void hello(@RequetsBody HelloData data) {}

일단 클래스 타입을 보면 후보군으로 "MappingJackson2HttpMessageConverter"가 가능하다

하지만 미디어 타입을 보면 "text/html"이므로 jackson이 지원하지 않는 미디어 타입이다

>> 따라서 이 경우는 오류가 발생한다


HTTP Request Data 읽는 과정 (JSON)

1. 일단 컨트롤러로 request가 들어오면 {@RequestBody or HttpEntity(RequestEntity)}를 활용해서 HTTP Request Message Body의 데이터를 읽는다

 

2. 이 때 여러가지 메시지 컨버터중에서 request로 들어온 메시지를 읽을 수 있는 컨버터를 찾기 위해서 각 컨버터별로 canRead()로 검증한다

 

3. (2) 과정에서 선택된 메시지 컨버터가 body의 데이터를 read()를 통해서 읽는다

 

HTTP Response Data 쓰는 과정 (JSON)

Controller에서 일련의 작업을 끝내고 Client에게 Response를 하려고 한다

 

1. Client에게 전달할 메시지를 write할 수 있는 메시지 컨버터를 "canWrite()"로 검증해서 찾아낸다

  • 이 때 Client가 request로 보낸 header의 "Accept"를 지원하는 메시지 컨버터를 찾아야 한다

 

2. (1) 과정에서 선택된 메시지 컨버터가 write()를 통해서 body에 데이터를 작성한다