도입
HTTP의 바디에 값을 넘겨줄 때 view를 활용하여 html을 생성해서 보내줄 수도 있고 간단하게 json이나 String 형식으로 넘겨줄 수 있다. json이나 String형식으로 넘겨줄때는 HTTP Message Converter를 사용하면 편리하게 넘겨줄 수 있다.
오늘은 HTTP Message Converter를 알아보도록 하겠다.
HTTP Message Converter
HttpMessageConverter는 requset로 넘어온 body 데이터 값을 받아오거나 혹은 response로 데이터를 body에 보낼 때 적절하게 변환해주는 역할을 수행한다.
예를들어 @ResponseBody annotation이 붙어있는 메소드가 실행이 될 때 적절한 HTTP Message Converter를 사용해 body에 데이터를 정상적으로 보내주는 것이다.
우리가 @RequestBody annotation만을 사용해 Body정보를 손쉽게 가져올 수 있는 이유도 바로 HTTP Message Converter가 있어서이며, @ResponseBody를 사용해 간단하게 Return Value를 Body에 넣어 전송할 수 있던것도 모두 HTTP Message Converter를 사용하기 때문이다.
적절한 HTTP Message Converter 찾기
@ResponseBody를 처리할 때를 예를들어 보겠다. 스프링은 적절한 HTTP Message Converter를 찾기 위해서는 2가지 정보를 확인한다. 메소드의 return되는 타입 그리고 Accept header정보이다. 모든 Converter를 돌며 적절한지 확인하기 위해 canWrite() 메소드를 사용하여 체크한다. 이 때 Return Type과 Media Type(Response의 경우 Accept header)를 확인하는 것이다.
자세히 알아보면 우선순위를 고려하여 char[] -> String -> Json -> ... 순서로 처리하는 HTTP MessageConverter를 확인하여 적절한 것인지 체크하게 된다. 만약 String 타입의 반환형이 왔다면, char[]를 체크 후 아닌 것을 확인하고 String을 체크하는 StringHttpMessageConverter를 확인한다. Return Type을 확인하고 String인것을 확인하면 Media Type을 체크하게 된다.
이 때 String의 Media Type은 */*(: 어떤 타입이든 모두 사용 가능) 이므로 적절한 HTTP Message Converter로 StringHttpMessageConverter가 채택되고 해당 Converter에서 write()를 실행하게 되는 것이다.
우선순위상 String이 Json의 앞에 있으므로 Media Type이 Json이고 Return 값이 String이라면 Json을 처리하는 Converter가 아닌 String을 처리하는 Converter가 실행되는 것도 알수 있다.
추가로 위 예시에서는 response에 대한 처리를 예로 들때 canWrite와 write 메소드를 사용함을 알 수 있는데, request에서는 canRead와 read를 사용하게 되며 처리 과정은 위와 동일한 방법으로 처리한다.
언제 HTTP Message Converter가 실행될까?
그렇다면, Spring MVC의 구조에서 언제 HTTP Message Converter가 실행되는지 알아보자.
클라이언트에서 HTTP 요청이 들어오면 관련 HTTP 요청을 처리할 수 있는 핸들러를 찾게된다.(핸들러는 Controller다.)
핸들러를 찾았으면 해당 핸들러를 적절하게 adapt할 수 있는 Handler adapter를 조회하게 된다.
찾은 Handler adapter가 handler에게 필요한 정보를 전달 후 실행하게 되고 Handler가 종료되면 반환을 하며 response를 처리하게 된다. 이 때 View를 사용해야 한다면 ViewResolver가 개입하여 적절한 View를 반환받고 model에서 데이터를 받아 랜더링하여 응답을 하게 된다.
우리는 @RequestBody, @RequestParam과 같은 annotation을 사용하면 쉽게 쿼리파라미터의 변수와 body의 값을 가져와 사용할 수 있다. Spring에서는 Param변수와 Body의 값을 가져와 전달하는 것은 핸들러 어댑터가 수행하는 것을 알 수 있고, 해당 값을 가져오기 위해 Argument Resolver를 사용하게 된다. Argument Resolver의 역할은 호출을 위해 파라미터를 지원해 줄수 있는지 체크(supportsParameter())하고 객체를 생성(resolverArgument())하여 전달해주는 역할을 수행하게 된다.
이 때 @RequestBody 혹은 HttpEntity로 메시지 처리 요청이 오면 HTTP Message Converter가 실행된다.
핸들러를 처리하고 마지막에 Return이 될때 HandlerMethodReturnValueHandler 즉 ReturnValueHandler가 실행된다. ReturnValueHandler 덕분에 우리는 Controller에서 return으로 String의 뷰 이름만을 반환할 때 해당 뷰로 랜더링될 수 있게 처리가 되는 것이다. 이 때 @ResponseBody가 있거나 HttpEntity로 return되는 경우 HTTP Message Converter가 실행된다.
배운내용
1. HTTP의 Body에 대한 정보를 request혹은 response를 편리하게 하기 위해 HTTPMessageConverter가 이용된다.
2. 적절한 Converter를 사용하기 위해 Controller의 Return Type과 Media Type을 우선순위를 고려하여 체크하고 사용한다.
3. HTTPMessageConverter는 request에서는Argument Revolver, response에서는 ReturnValueHandler에서 사용된다. 둘다 Body에 대한 처리를 할 때 실행이 된다(@RequestBody, @ResponseBody, HttpEntity)
이 글은 김영한님의 'Spring MVC 1편' 강의를 공부한 후 작성한 글입니다.
'Back-end > Spring' 카테고리의 다른 글
PRG Post/Redirect/Get (0) | 2021.11.18 |
---|---|
Server Side Rendering (Thymeleaf) (0) | 2021.11.16 |
SSR Response, Response Body (0) | 2021.11.08 |
Request Body 받아오기 (0) | 2021.11.04 |
Request Parameter 가져오기 (0) | 2021.11.04 |