[MVC1] 8. HTTP 메시지 컨버터

kiwonkim·2021년 7월 15일
0
post-thumbnail

지난 포스팅

요청은 파라미터로. 응답은 반환값으로 해준다.
그 중 Body를 통한 데이터 송수신에서 @RequestBody, @ResponseBody, HttpEntity 는 Body의 정보를 가져오고, Body 에 정보를 담아 응답할 때 사용한다.

Body 에 담긴 요청 메시지의 객체 or String 변환.
응답을 Body에 담을 때 Text or Json의 변환.
위 두 변환은 기준이 무엇이고 누가 해주는걸까?


Argument Resolver 와 ReturnValue Handler

컨트롤러의 파라미터는 @RequestParam, @ModelAttribute, HttpServletRequest 등 다양한 타입의 객체를 입력만 하면 제공해준다.
컨트롤러의 반환 값은 객체, 문자열, 뷰 상대 경로 등 다양한 반환 타입을 제공한다.
이렇게 편리한 다양성은 누가 제공해주는 걸까?

디스패쳐 서블릿이 핸들러 처리를 위해 어댑터를 호출하면. 어댑터는 Argument Resolver를 호출한다. Argument Resolver는 컨트롤러가 필요하다고 파라미터에 입력한 객체들을 생성해준다. 이 때 Model, HttpServletRequest, @ModelAttribute 등 컨트롤러가 요청한 객체를 생성하여 파라미터로 넘겨준다.

Argument Resolver가 제공한 파라미터를 사용한 컨트롤러는 결과 값을 반환한다. 뷰 상대경로, ModelAndView 객체, @ResponseBody 등 다양한 반환형식을 지원하는데. 컨트롤러의 반환값은 ReturnValueHandler 로 넘겨져 형식에 알맞는 처리를 수행하게 된다.

아규먼트 리졸버는 컨트롤러가 파라미터에 요청한 다양한 객체들을 생성해서 넘겨준다. 리턴벨류 핸들러는 컨트롤러의 다양한 반환값에 알맞는 처리를 해준다. 둘 모두 핸들러 어댑터와 값을 주고 받는다.



HTTP 메시지 컨버터

그러면 HTTP 메시지 컨버터는 뭘까? HTTP 메시지 컨버터는 메시지 바디와 컨트롤러 객체간 변환을 수행하며, Body를 처리해야하는 아규먼트 리졸버와 리턴 밸류 핸들러가 사용한다.

여러 종류의 아규먼트 리졸버 중 @RequestBody 나 HttpEntity 를 활용해 요청 Body 내용을 반영한 객체를 만들어야 하는 리졸버가, 요청 바디의 내용 변환을 위해 HTTP 메시지 컨버터를 사용한다. 아규먼트 리졸버는 "요청의 content-type"과 "함께 들어온 파라미터 타입"을 고려하여 어떤 메시지 컨버터를 사용할지 결정한다.

//EX1
content-type: application/json
@RequestMapping
void hello(@RequetsBody String data) {}

content-type : Json & 클래스 타입 : String
RequestBody 처리 아규먼트 리졸버 : 요청 바디는 json 인데, String으로 받길 원하네. 스트링 메시지 컨버터로 바디를 String 으로 바꿔 파라미터로 넘겨줌.


//Ex2
content-type: application/json
@RequestMapping
void hello(@RequetsBody HelloData data) {}

content-type : Json & 클래스 타입 : 객체
아규먼트 리졸버 : 요청 바디는 json인데, 객체로 받길 원하네. 잭슨 메시지 컨버터를 사용해 요청 바디를 객체로 변환해 파라미터로 넘겨줌.


//Ex3
content-type: text/html
@RequestMapping
void hello(@RequetsBody HelloData data) {}

content-type : html & 클래스 타입 : 객체
아규먼트 리졸버 : 요청 바디는 html 인데 객체로 받길 원하네. 어떻게 해야하지? 에러 발생.


여러 종류의 리턴밸류 핸들러 중 @ResponseBody나 HttpEntity 같이 Body 에 직접 데이터를 저정하는 방식의 리턴밸류 핸들러가, 반환값을 어떤 타입으로 바디에 저장할지 결정하기 위해 HTTP 메시지 컨버터를 사용한다. 리턴밸류 핸들러는 "반환 타입"과 "요청의 accept헤더"를 고려하여 어떤 메시지 컨버터를 사용할지 결정한다.

accept : application/json
@ResponseBody
HelloData hello() {}

리턴밸류 핸들러: 클라이언트가 json 으로 받길 원하네, 반환형이 객체네. 잭슨 메시지 컨버터 써서 객체를 json으로 바꿔서 응답 body에 담아야겠다.


아규먼트 리졸버가 생성하는 파라미터 중 Body를 필요로하는 파라미터는 메시지 컨버터를 사용해 Body를 명시한 타입으로 변경후 파라미터로 넣어준다. 메시지 컨버터는 content-type + 파라미터 클래스로 객체타입을 결정한다.

Body에 직접 값을 입력하는 반환의 경우, 리턴밸류 핸들러가 메시지 컨버터를 사용해 반환값을 클라이언트가 원하는 타입으로 변환 후 응답Body에 입력한다. 메시지 컨버터는 accept + 반환 클래스로 응답Body타입을 결정한다.



본 글은 김영한님의 "스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술" 강의내용 및 이해한 내용을 정리한 것입니다.

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard

0개의 댓글

관련 채용 정보