@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 에 대해 공부해볼거당
'이론 > Spring' 카테고리의 다른 글
[Spring Test] private로 선언된 메소드를 어떻게 테스트 할 수 있을까 (0) | 2022.01.23 |
---|---|
스프링 HTTP Message Body 와 Message Converter 2 - RequestMappingHandlerAdapter (0) | 2021.12.18 |
[TEST] 스프링에서의 TEST, 그리고 일반적 TEST (0) | 2021.10.29 |
[Spring Boot] Spring Security (0) | 2021.08.15 |
[Spring Boot] Spring MVC 구조 / 핸들러 매핑과 핸들러 어댑터 (0) | 2021.08.08 |