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 |
댓글