스프링MVC

HTTP 메시지 컨버터

salmon16 2023. 8. 23. 20:48

HTTP API처럼 JSON 데이터를 HTTP 메시지 바디에 직접 읽거나 쓰는 경우 HTTP 메시지 컨버터를 사용하면 편리하다.

 

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

HTTP 요청 : @RequestBody, HttpEntity(RequestEntity),

HTTP 응답 : @ResponseBody, HttpEntity(ResponseEntity)

 

HTTP 메시지 컨버터는 인터페이스로 구현되어 있다 인터페이스의 주요 함수를 살펴보자

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;
}

canRead, canWrite : 메시지 컨버터가 해당 클래스, 미디어 타입을 지원하는지 체크

read, write : 메시지 컨버터를 통해 메시지를 읽기, 쓰기 기능

 

스프링 부트는 다양한 메시지 컨버터 구현체를 제공한다. 

대상 클래스 타입과 미디어 타입 둘을 체크해서 우선순위가 높은 컨버터 구현체부터 사용 가능한지 체크하고 불가능하다면 다음 우선순위 컨버터로 넘어가서 검사 후 사용이 가능하면 선택된다.

 

일부 스프링 부트 기본 메시지 컨버터 이다.

0순위 = ByteArrayHttpMessageConverter

1순위 = StringHttpMessageConverter

2순위 = MappingJackson2HttpMessageConverter

 

  • ByteArrayHttpMessageConverter : byte[] 데이터를 처리한다.
    • 클래스 타입: byte[] , 미디어타입: */* ,
    • 요청 예) @RequestBody byte[] data
    • 응답 예) @ResponseBody return byte[] 쓰기 미디어타입 application/octet-stream
  • StringHttpMessageConverter : String 문자로 데이터를 처리한다.
    • 클래스 타입: String , 미디어타입: */*
    • 요청 예) @RequestBody String data
    • 응답 예) @ResponseBody return "ok" 쓰기 미디어타입 text/plain
  • MappingJackson2HttpMessageConverter : application/json
    • 클래스 타입: 객체 또는 HashMap , 미디어타입 application/json 관련
    • 요청 예) @RequestBody HelloData data
    • 응답 예) @ResponseBody return helloData 쓰기 미디어타입 application/json 관련 

 

HTTP 요청 데이터를 읽는 과정을 보자

1.HTTP 요청이 오고 컨트롤러에서 @RequestBody 또는 HttpEntity파라미터를 사용한다.

2. 맞는 메시지 컨버터를 찾기 위해 canRead()를 호출한다

3. canRead()에서 대상 클래스 타입을 지원하는지 Content-type 미디어 타입을 지원하는지 체크

4.read()를 호출해서 객체를 생성하고 반환한다.

 

HTTP 응답 데이터가 생성되는 과정을 보자

1. 컨트롤러에서 @ResponseBody, HttpEntity로 값이 반환될 때 

2. 메시지 컨버터가 메시지를 쓸 수 있는지 확인하기 위해 canWrite()를 호출한다.

3. canwrite()에서 대상 클래스 타입을 지원하는지 HTTP요청의 Accept 미디어 타입을 지원하는지 체크

4.write() 메서드를 호출해서 HTTP응답 메시지 바디에 데이터를 생성한다.

 

HTTP 메시지 컨버터는 스프링 MVC 어디쯤에서 사용되는지 알아보자

 

 

애노테이션 기반의 컨트롤러는 매우 다양한 파라미터를 사용할 수 있다 HttpServletRequest, Model, @RequsetParam, ModelAttribute 등 이렇게 유연하게 처리할 수 있는 이유는 ArgumentResolver 덕분이다.

 

애노테이션 기반 컨트롤러를 처리하는 RequestMappingHandlerAdapter는 ArgumentResolver를 호출해서 컨트롤러가 필요하는 다양한 파라미터의 값(객체)을 생성한다.

 

ArgumentResolver 구현 코드를 살펴보자

public interface HandlerMethodArgumentResolver {
	boolean supportsParameter(MethodParameter parameter);
	@Nullable
	Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
	NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}

supportsParameter()을 호출해서 파라미터를 처리할 수 있는지 체크하고 할 수 있으면 resolveArgument를 호출해서 객체를 생성한다.

ReturnValueHandler도 ArgumentResolver와 비슷하게 동작한다.

 

HTTP메시지 컨버터가 어디 있는지 보자

ArgumentResolver, ReturnValueHandler에서 HTTP 메시지 컨버터를 사용하는 경우(@RequestBody, HttpEntity, @ResponseBody) 호출해서 사용해서 객체를 생성한다.

 

출처 : 스프링MVC 1편 - 백엔드 웹 개발 핵심 기술 김영한

'스프링MVC' 카테고리의 다른 글

HTTP 응답 - 정적 리소스, 뷰 템플릿  (0) 2023.08.23
HTTP 요청 -기본, 헤더, 데이터 조회  (0) 2023.08.22
스프링 MVC 기본 기능  (0) 2023.08.21
로깅 간단하게 알아보기  (0) 2023.08.18
스프링 MVC 시작하기  (0) 2023.08.10