Spring Boot
[Spring] Spring MVC 프레임워크의 구조, HttpMessageConverter
HEY__
2022. 8. 9. 11:23
728x90
이 글은 공부를 하면서 알게 된 내용들을 기록하는 글 입니다. 오류나 고쳐야 할 사항들이 있다면 지적 부탁드립니다!
⛅️ 스프링 MVC의 구조
✅ 동작 순서
- DispatcherServlet이 핸들러 매핑 정보를 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
- 핸들러 어댑터 목록에서 핸들러를 처리할 수 있는 핸들러 어댑터를 조회한다.
- DispatcherServlet이 handle(handler)를 통해 핸들러 어댑터를 실행한다.
- 핸들러 어댑터를 통해 실제 핸들러를 실행한다.
- 핸들러 어댑터가 핸들러가 반환한 정보를 ModelAndView로 변환해서 반환한다.
- DispatcherServlet이 viewResolver를 통해 view의 논리 이름을 물리 이름으로 바꾸고, 렌더링 역할을 담당하는 view 객체를 반환한다.
- view를 통해서 view를 rendering한다.
즉, 핸들러 어댑터를 통해 핸들러(컨트롤러)가 실행되고, 핸들러 어댑터가 반환한 내용을 통해 viewResolver가 실제 view를 반환한다.
그리고 view의 render를 통해 HTML 응답을 클라이언트에게 전달하는 것이다.
✅ DispatcherServlet
- DispatcherServlet도 HttpServlet을 상속받아서 사용하고, 서블릿으로 동작한다.
- 스프링 부트는 DispatcherServlet을 서블릿으로 자동 등록하면서 모든 경로(urlPatterns="/")에 대해 매핑한다.
- 더 자세한 경로가 우선순위가 높기 때문에, 등록한 다른 서블릿도 함께 동작한다.
⛅️ HTTP 메세지 컨버터
✅ HTTP 메세지 컨버터 개요
- HTTP 메세지 컨버터는 JSON 데이터를 HTTP 메세지 바디에서 직접 읽거나 쓰는 경우 사용하면 편하다.
- 응답의 경우 클라이언트 HTTP Accept 헤더, 서버의 컨트롤러 반환 타입 정보를 조합하여 HttpMessageConverter를 선택한다.
- HTTP 요청인 경우 Message converter가 해당 클래스, 미디어 타입을 지원하는지 체크하고,
HTTP 응답인 경우 메세지 컨버터를 통해서 메세지를 읽고 쓰는 기능을 지원한다.
✅ HTTP 메세지 컨버터 적용 시기
- HTTP 요청 - @RequestBody, RequestEntity(HttpEntity)
- HTTP 응답 - @ResponseBody, ResponseEntity(HttpEntity)
✅ 다양한 Message converter
0 = ByteArrayHttpMessageConverter
1 = StringHttpMessageConverter
2 = MappingJackson2HttpMessageConverter
- 스프링 부트는 다양한 Message converter를 제공하는데, 클래스 타입과 미디어 타입을 확인하여 만족하면 해당 메세지 컨버터를 사용하고, 그렇지 않으면 다음 메세지 컨버터를 살펴본다.
- ByteArrayHttpMessageConverter
byte[] 데이터를 처리. 클래스 타입: byte[] , 미디어타입: */* - StringHttpMessageConverter
String 문자로 데이터를 처리. 클래스 타입: String , 미디어타입: */* - MappingJackson2HttpMessageConverter
application/json. 클래스 타입: 객체 또는 HashMap , 미디어타입 application/json 관련
✅ Message Converter 우선순위 예시
// 클래스 타입이 String 이고, Content-type이 application/json이므로 StringHttpMessageConverter 사용
@RequestMapping
void hello(@RequetsBody String data) {}
// 클래스 타입이 객체, 미디어 타입이 application/json이기 때문에 MappingJackson2HttpMessageConveter 사용
@RequestMapping
void hello(@RequetsBody HelloData data) {}
⛅️ HTTP 요청, 응답 데이터 처리 과정
✅ HTTP 요청(request) 데이터 읽기
- HTTP 요청이 오고, 컨트롤러에서 @RequestBody , HttpEntity 파라미터를 사용한다.
- 메시지 컨버터가 메시지를 읽을 수 있는지 확인하기 위해 canRead() 를 호출한다.
- 대상 클래스 타입을 지원하는지 확인. ex) @RequestBody 의 대상 클래스 ( byte[] , String , MemberData)
- HTTP 요청의 Content-Type 미디어 타입을 지원하는지 확인. ex) text/plain , application/json , */*
- canRead() 조건을 만족하면 read() 를 호출해서 객체 생성하고, 반환한다.
✅ HTTP 응답(response) 데이터 생성
- 컨트롤러에서 @ResponseBody , HttpEntity를 통해 값이 반환된다.
- 메시지 컨버터가 메시지를 쓸 수 있는지 확인하기 위해 canWrite() 를 호출한다.
- 대상 클래스 타입을 지원하는지 확인. ex) return의 대상 클래스 ( byte[] , String , HelloData )
- HTTP 요청의 Accept 미디어 타입을 지원하는지 확인. ex) text/plain , application/json , */*
- canWrite() 조건을 만족하면 write() 를 호출해서 HTTP 응답 메시지 바디에 데이터를 생성한다.
728x90