클라이언트에서 서버로 요청 데이터를 전달할 때는 주로 다음과 같은 방법을 통해 전달한다.
- GET + 쿼리 파라미터
- POST - HTML Form
- HTTP Message Body
반대로 서버에서 클라이언트에 응답 데이터를 전달할 때는 다음과 같다.
- 정적/동적 HTML
- HTTP Message Body
HTTP API를 제공하는 경우에는 HTTP Message Body에 JSON, XML, TEXT 형식으로 데이터를 직접 담아서 요청 및 응답을 처리한다.
Spring에서는 HttpEntity 객체나 @RequestBody, @ResponseBody 어노테이션을 사용하면 데이터를 직접 매핑할 필요 없이 자동으로 요청 및 응답 데이터를 적절한 데이터 형식으로 변환해준다.
@Slf4j
@Controller
@RequestMapping("/test")
public class Test {
@ResponseBody
@PostMapping("/httpEntity")
public String httpEntity(HttpEntity<Hello> data) {
log.info("Http Header={}", data.getHeaders());
log.info("Http Body={}", data.getBody());
return "ok";
}
@ResponseBody
@PostMapping("responseBody")
public String responseBody(@RequestBody Hello data) {
log.info("data={}", data);
return "ok";
}
@Data
static class Hello {
private String name;
private int age;
}
}
실제로 JSON 형식의 데이터를 날려보면 별다른 매핑을 구현하지 않아도 원하는 대로 처리되는 것을 확인할 수 있다.
그렇다면 스프링은 내부에서 어떠한 원리로 요청 및 응답 데이터를 적절한 데이터로 변환해주는 것일까?
이는 HTTP 메시지 컨버터라는 기능을 통해서 제공해준다.
HTTP 메시지 컨버터는 데이터의 클래스 타입과 미디어 타입을 체크하여 알맞은 형식의 데이터로 변환해주는 친구이다.
- canRead(), canWrite() : 메시지 컨버터가 데이터의 클래스 타입과 미디어 타입을 지원하는지 확인
- read(), write() : 지원한다면 메시지를 적절한 데이터로 변환(읽기, 쓰기)
스프링 부트는 다양한 타입의 메시지 컨버터를 지원하며 이들은 우선순위를 가진다.
대표적인 메시지 컨버터는 다음과 같다.
- ByteArrayHttpMessageConverter(우선순위 0)
- StringHttpMessageConverter(우선순위 1)
- MappingJackson2HttpMessageConverter(우선순위 2)
만약, JSON 형식의 객체 데이터 {"name":"hello", "age":20}를 전송하면 MappingJackson2HttpMessageConverter가 적절한 데이터로 변환해준다.
MappingJackson2HttpMessageConverter는 클래스 타입으로 객체 or HashMap을 지원하고, 미디어 타입으로 application/json을 지원해주기 때문이다.
HTTP 메시지 컨버터의 동작원리는 이해하였다. 그렇다면 HTTP 메시지 컨버터는 스프링 MVC의 동작 과정 중 어디서 적용되는 것일까?
HTTP 메시지 컨버터는 ArgumentResolver와 ReturnValueHandler가 사용한다.
스프링 MVC는 요청이 발생하면 핸들러 매핑, 핸들러 어댑터를 통해 요청을 처리할 수 있는 컨트롤러를 찾아준다.
그런데 우리는 요청을 @RequestParam, @ModelAttribute, @RequestBody, HttpEntity 등 다양한 타입의 인자값으로 받을 수 있었다.
컨트롤러에서 데이터를 사용하기 위해서는 다양한 타입의 인자값을 누군가가 적절한 데이터로 매핑시켜줘야 할 것이다.
이를 해결해주는 친구가 바로 ArgumentResolver이다. 반대로 ReturnValueHandler는 응답에서 다양한 타입의 인자값을 처리해준다.
즉, ArgumentResolver와 ReturnValueHandler는 요청, 응답 데이터를 적절한 데이터로 변환해주는 역할을 수행한다.
이때 다양한 타입의 데이터들 중 HttpEntity 객체나 @RequestBody, @ResponseBody 어노테이션을 가지는 데이터라면 HTTP 메시지 컨버터를 사용하여 데이터를 매핑시켜주는 것이다.
[ Reference ]
· https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
'IT 개인 공부 > Spring' 카테고리의 다른 글
[Spring] AOP란? (0) | 2021.09.09 |
---|---|
[Spring] 서블릿 필터 vs 스프링 인터셉터 (0) | 2021.09.05 |
[Spring] 빈 스코프(Scope) 종류 (0) | 2021.08.23 |
[Spring] 싱글톤 컨테이너 : CGLIB (0) | 2021.08.22 |
[Spring] 조회한 빈(Bean)이 모두 필요할때 처리하는 방법 (0) | 2021.08.19 |
댓글