Develop/Spring

[Spring] HTTP 메시지 컨버터

연로그 2021. 10. 10. 17:06
반응형

HTTP 메시지 컨버터란?

 

JSON 데이터를 HTTP 메시지 바디에서 직접 읽거나 쓰는 경우, HTTP 메시지 컨버터를 사용하면 매우 편리하다!

HTTP 메시지 컨버터란, 요청 본문에서 메시지를 읽어들이거나(@RequestBody), 응답 본문에 메시지를 작성할 때(@ResponseBody) 사용하는 컨버터다.

 

🔻 포스팅을 보기 전, @ResponseBody를 다시 살펴보자.

더보기
  1. 웹 브라우저가 "localhost:8080/hello-api" 접근
  2. 서버를 거쳐 helloController 호출
  3. helloController의 @ResponseBody를 통해 HttpMessageConverter가 호출
  4. return 타입에 따라 JsonConverter 또는 StringConverter를 이용해 return

 

@ResponseBody의 사용

  • HTTP의 Body에 문자 내용을 직접 반환
  • viewResolver 대신 HttpMessageConverter 동작
  • 기본 문자 처리: StringHttpMessageConverter
  • 기본 객체 처리: MappingJacksonHttpMessageConverter
  • 바이트 처리 등: HttpMessageConverter가 기본으로 등록

 

스프링 MVC가 HTTP 메시지 컨버터를 적용하는 경우

  • 요청: @RequestBody, HttpEntity(RequestEntity) 사용
  • 응답: @ResponseBody, HttpEntity(ResponseEntity) 사용

 

메시지 컨버터의 선택 기준

  • 요청: HTTP Content-Type 헤더와 서버 컨트롤러의 파라미터 타입 정보 이용
  • 응답: HTTP Accept 헤더와 서버 컨트롤러의 반환 타입 정보 이용

 

HTTP 메시지 컨버터 인터페이스

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 요청, 응답 양방향으로 사용
  • canRead(), canWrite(): 메시지 컨버터가 해당 클래스, 미디어 타입을 지원하는지 체크
  • read(), write(): 메시지 컨버터를 통해 메시지를 읽고 쓰는 기능

 

 

스프링 부트의 기본 메시지 컨버터

ByteArrayHttpMessageConverter
StringHttpMessageConverter
MappingJacksonHttpMessageConverter
...
  • 기본적으로 위의 컨버터들을 지원함
  • 대상 클래스 타입미디어 타입을 체크해 사용여부 결정
    (만족하지 않는 경우 다음 메시지 컨버터로 우선순위 넘어감)

  • ex1: @RequestBody String data 형식으로 요청이 오면 StringHttpMessageConverter 사용
  • ex2: @ResponseBody return helloData로 쓰고 미디어 타입 application/json인 경우 MappingJacksonHttpMessageConverter 사용

 

 

HTTP 요청 데이터 읽기

  1. HTTP 요청이 들어오고, 컨트롤러에서 @RequestBody나 HttpEntity 파라미터 사용
  2. 메시지 컨버터가 canRead() 호출    // 읽을 수 있는 메시지인지 확인
    - 대상 클래스 타입과 HTTP의 Content-Type 미디어 타입 지원하는지
  3. canRead() 만족 시 read() 호출해 객체 생성 및 반환

 

 

HTTP 응답 데이터 생성

  1. 컨트롤러에서 @ResponseBody나 HttpEntity로 값 반환
  2. 메시지 컨버터가 canWrite() 호출    // 메시지를 쓸 수 있는지 확인
    - 대상 클래스 타입과 HTTP의 Accept 미디어 타입 지원하는지
  3. canWrite() 만족 시 write() 호출해 HTTP 응답 메시지 바디에 데이터 생성

 

 


HTTP 메시지 컨버터의 실행

 

그렇다면 이제 궁금한 것이 하나 생겼다. 🤔❓

HTTP 메시지 컨버터는 어디서 실행되는걸까?

 

SpringMvc 구조를 다시 보자

  1. HTTP 요청이 들어오면 핸들러 조회
  2. 핸들러를 처리할 수 있는 핸들러 어댑터 조회
  3. handle(handler)
  4. handler 호출
  5. ModelAndView 반환
  6. viewResolver 호출
  7. View 반환
  8. render(model) 호출

 

위 과정에서 4번 과정을 주목해보자.

어노테이션 기반의 핸들러(컨트롤러)의 여러 파라미터를 생성해서 호출할 수 있는 '핸들러 어댑터'

이 어댑터가 HTTP 메시지 컨버터와 관련이 있다.

 

먼저, @RequestMapping을 처리하는 핸들러 어댑터인 RequestMappingHandlerAdapter를 자세히 살펴보자.

  1. ArgumentResolver 호출
    ArgumentResolver: 매우 다양한 종류의 파라미터를 유연하게 처리해 파라미터 값(객체) 생성
  2. 파라미터 값이 준비되면 컨트롤러를 호출하며 값을 넘겨줌

 

🔻 ArgumentResolver 코드 살펴보기

더보기

interface를 열어보면 아래와 같다.

public interface HandlerMethodArgumentResolver {
	boolean supportsParameter(MethodParameter parameter);

	@Nullable
	Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}

supportsParameter()를 통해 해당 파라미터를 지원하는지 확인해보고,
resolveArgument()를 통해 파라미터(객체)를 생성해서 반환해준다.

이렇게 생성된 객체는 컨트롤러로 넘어가게 된다.

 

추가적으로 이 인터페이스를 확장하면 원하는 ArgumentResolver를 생성할 수도 있다.

 

그럼 이제 본격적으로 HTTP 메시지 컨버터는 어디있을까?

 만약 ArgumentResolver에 요청하는 파라미터가 @RequestBody 또는 HttpEntity인 경우 HTTP 메시지 컨버터를 사용해 'read' 한다. 응답의 경우에도 @ResponseBody 또는 HttpEntity를 처리하는 ReturnValueHandler에서 HTTP 메시지 컨버터를 호출해 응답 결과를 'write' 한다.

 

 


본 게시글은 김영한 님의 '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 강의를 구매 후 정리하기 위한 포스팅입니다.

내용을 임의로 추가, 수정, 삭제한 부분이 많으며 정확한 이해를 위해서 강의를 구매하시는 것을 추천 드립니다.

 

inf.run/B756

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

www.inflearn.com

 

반응형