스프링 #6 메시지 컨버터

함형주·2022년 10월 15일
0

spring

목록 보기
6/12

질문, 피드백 등 모든 댓글 환영합니다.

이전 블로그에서 HTTP 요청을 처리하는 방법을 정리하며 스프링 MVC가 어떻게 데이터를 적절히 인식하여 변환하는지에 관한 궁금증을 남겼습니다.

스프링 MVC는 HandlerMethodArgumentResolver, HttpMessageConverter 등을 통해 해당 기능을 제공합니다.

HandlerMethodArgumentResolver (ArgumentResolver)

먼저 스프링 MVC가 어떻게 컨트롤러에 파라미터를 생성하여 전달하는지 알아보겠습니다.

어노테이션 기반의 컨트롤러를 사용한다면 RequestMappingHandlerAdater(요청 매핑 핸들러 어댑터)가 사용됩니다.
요청 매핑 핸들러 어댑터가 ArgumentResolver를 통해 컨트롤러의 어노테이션이나 파라미터 정보를 인식하고 이를 기반으로 적절한 파라미터를 생성하여 전달합니다.
ex) @ModelAttribute가 사용되고 파라미터로 Model, HttpServletRequest, XxObject(임의의 객체)가 사용된다면 각 객체를 생성하고 HTTP 요청 정보를 기반으로 적절히 매핑하여 전달합니다.

어노테이션 기반의 컨트롤러가 다양한 파라미터를 사용할 수 있는 이유는 스프링 MVC가 ArgumentResolver(인터페이스)의 구현체 수십 가지를 미리 구현해 두었기 때문입니다.

가능한 파라미터 목록은 스프링 공식 문서에서 확인할 수 있습니다.

ArgumentResolversupportsParameter()resolveArgument() 두 메서드를 제공합니다.
supportsParameter()를 통해 해당 컨트롤러의 파라미터를 지원하는지 체크하고 resolveArgument()로 객체를 생성합니다.

추가로 컨트롤러에서 반환된 값은 HandlerMethodReturnValueHandler(ReturnValueHandler)를 통해 변환하고 처리합니다. ArgumentResolver와 유사하게 동작하며 컨트롤러에서 ModelAndView를 반환하지 않고 String을 반환해도 같은 응답이 출력된 이유가 이 때문입니다.

사용 가능한 반환 타입 목록은 스프링 공식 문서에서 확인할 수 있습니다.

HttpMessageConverter (메시지 컨버터)

이제 스프링 MVC가 어떻게 데이터를 변환하는지 알아보겠습니다.

스프링 MVC는 HttpMessageConverter를 통해 HTTP 요청 데이터나 응답 데이터를 변환할 수 있습니다.

HTTP 요청의 경우 @RequestBody, HttpEntity(RequestEntity)가 있을 때,
응답의 경우 @ResponseBody, HttpEntity(ResponseEntity)가 있을 때 메시지 컨버터가 작동합니다.

중요한 메시지 컨버터 두 가지를 알아보면

StringHttpMessageConverter : String 타입으로 데이터 처리

  • 요청 예시) @RequestBody String data
  • 응답 예시) @ResponseBody {return "ok";} 미디어타입 text/plain

MappingJackson2HttpMessageConverter : 객체, HashMap, application/json 처리

  • 요청 예시) @RequestBody User user
  • 응답 예시) @ResponseBody {return user;} 미디어타입 application/json

가장 많이 사용하는 MappingJackson2HttpMessageConverter 가 작동하는 방식을 더 자세히 알아보면

HTTP 요청 -> 컨트롤러에서 @RequestBody, HttpEntity 여부 확인 -> canRead()로 대상 클래스 타입(객체 or HashMap)과 미디어 타입(application/json) 여부 확인 -> 통과 시 read()로 객체 생성 및 반환

컨트롤러에서 @ResponseBody, HttpEntity 여부 확인 -> canWrite()로 return 대상 클래스 타입(객체 or HashMap)과 미디어 타입(application/json) 여부 확인 -> 통과 시 write()로 HTTP 메시지 바디에 데이터 생성

메시지 컨버터가 사용되는 위치

블로그를 읽으며 어느정도 예상 하셨겠지만 메시지 컨버터는 HTTP 요청을 컨트롤러의 파라미터로 바인딩하는 시점과 반환 값을 응답 메시지로 변환할 때 사용되므로 ArgumentResolverReturnValueHandler에서 사용됩니다.

각 타입에 맞는 ArgumentResolverReturnValueHandler가 대부분 구현되어 있고 이들이 HTTP 메시지 컨버터를 이용하여 데이터를 변환하고 처리합니다.

추가로 HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler, HttpMessageConverter는 모두 인터페이스로 제공되므로 필요하다면 직접 기능을 확장하여 사용할 수 있습니다.
WebMvcConfigurer을 상속받은 클래스에 addArgumentResolvers()extendMessageConverters()를 이용하여 등록 후 스프링 빈에 등록하면 사용할 수 있습니다.

사진은 김영한님의 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 강의자료에서 발췌하였습니다.

profile
평범한 대학생의 공부 일기?

0개의 댓글