본문 바로가기
이론/Spring

스프링 HTTP Message Body 와 Message Converter 1

by 6161990 2021. 11. 20.

@Controller에서 String return 하면 ViewResolver로 인해 view로 가고 

@RestController에서는 String return 하면 HttpMessageConverter로 인해 body 내용이 전달된다.

기본 문자 처리는 String HttpMessageConverter
기본 객체처리는 MappingJackson2HttpMessageConverter이 기여한다. 

이렇게 똑똑하게 움직일 수 있는 이유가 뭘까. 

 

📌 Message Converter

우선, 

스프링 MVC는 다음의 경우에 HTTP 메시지 컨버터를 적용한다.
HTTP 요청 @RequestBody , HttpEntity(RequestEntity) 
HTTP 응답 @ResponseBody , HttpEntity(ResponseEntity) 

 

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;


}

 

 

HTTP 메시지 컨버터는 HTTP 요청, HTTP 응답 둘 다 사용된다.

  • canRead() , canWrite() : 메시지 컨버터가 해당 클래스, 미디어타입을 지원하는지 체크
  • read() , write() : 메시지 컨버터를 통해서 메시지를 읽고 쓰는 기능

 

스프링 부트 기본 메시지 컨버터 우선 순위 

0 = ByteArrayHttpMessageConverter : byte[] 데이터를 처리한다.
    클래스 타입: byte[] , 미디어타입: */* ,
    요청 예) @RequestBody byte[] data
    응답 예) @ResponseBody return byte[] 쓰기 미디어타입 application/octet-stream

1 = StringHttpMessageConverter : String 문자로 데이터를 처리한다.
   클래스 타입: String , 미디어타입: */*
   요청 예) @RequestBody String data
   응답 예) @ResponseBody return "ok" 쓰기 미디어타입 text/plain

2 = MappingJackson2HttpMessageConverter : application/json
   클래스 타입: 객체 또는 HashMap , 미디어타입 application/json 관련
   요청 예) @RequestBody HelloData data
   응답 예) @ResponseBody return helloData 쓰기 미디어타입 application/json 관련

스프링 부트는 다양한 메시지 컨버터를 제공하는데, 대상 클래스 타입과 미디어 타입 둘을 체크해서 사용여부를 결정한다. 만약 만족하지 않으면 다음 메시지 컨버터로 우선순위가 넘어간다.

 

 

HTTP 요청 데이터 읽기

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

 

HTTP 응답 데이터 생성

  • 컨트롤러에서 @RequestBody, HttpEntity 파라미터를 사용한다. 
  • 메세지 컨버터가 메시지를 쓸 수 있는지 확인하기 위해 canWrite( )를 호출한다.
    • 대상 클래스 타입을 지원하는가. EX ) return의 대상 클래스 ( byte[] , String , HelloData )
    • HTTP 요청의 Accept 미디어 타입을 지원하는가. 더 정확히는 @RequestMapping의 produces. EX ) text/plain, application/json, */*
  • canWrite()조건을 만족하면 write()를 호출해서 HTTP 응답 메세지 바디에 데이터를 생성한다.

 

📌 그렇다면, HTTP 메세지 컨버터는 스프링 MVC에서 어디쯤에서 사용되고 있는걸까?

답은 @RequestMapping을 처리하는 핸들러 어댑터인 RequestMappingHandlerAdapter(요청 매핑 핸들러 어댑터)에 있다. 

 

다음주에 RequestMappingHandlerAdapter 에 대해 공부해볼거당