김영한 강사님의 '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 강의 정리
2022.02.06~02.07 진행
강의를 듣고 개인적으로 정리한 글입니다. 코드와 그림 출처는 김영한 강사님께 있습니다. 문제 있을 시 알려주세요.
언제 HttpMessageConverter 가 적용되는가
스프링 MVC는 다음의 경우에 viewResolver 대신 HttpMessageConverter를 적용한다.
- HTTP 요청 :
@RequestBody
,HttpEntity(RequestEntity)
- HTTP 응답 :
@ResponseBody
,HttpEntity(ResponseEntity)
HttpMessageConverter 동작과정
HTTPMessageConverter 인터페이스를 간략히 알아보자면, 다음과 같다.
package org.springframework.http.converter;
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
List<MediaType> getSupportedMediaTypes();
T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;
}
HTTP 요청/응답이 오고, 컨트롤러에서 HttpMessageConverter가 적용되면
canRead()
나canWrite()
을 호출해 대상 클래스 타입과 미디어 타입을 체크한다.- HTTP 요청:
@RequestBody
의 대상 클래스(파라미터) 체크, 요청의 Content-type을 지원하는가 체크 - HTTP 응답: return 의 대상 클래스 체크, 응답의 Accept를 지원하는가 체크
- HTTP 요청:
- 조건을 만족하면
- HTTP 요청:
read()
를 호출해서 객체를 생성 및 반환 - HTTP 응답:
write()
를 호출해서 HTTP 응답 메시지 바디에 데이터를 생성
- HTTP 요청:
- 만족하지 않으면 다음 메시지 컨버터로 우선순위가 넘어간다.
스프링 부트가 제공하는 메시지 컨버터
스프링 부트는 다음과 같이 다양한 메시지 컨버터를 제공한다. 숫자가 작은 순으로 우선순위가 높다.
0 = ByteArrayHttpMessageConverter
1 = StringHttpMessageConverter
2 = MappingJackson2HttpMessageConverter
ByteArrayHttpMessageConverter
- 클래스 타입:
byte[]
- 미디어 타입:
*/*
- 응답시 미디어 타입:
application/octet-stream
- 클래스 타입:
StringHttpMessageConverter
- 클래스 타입:
String
- 미디어 타입:
*/*
- 응답시 미디어 타입:
text/plain
- 클래스 타입:
MappingJackson2HttpMessageConverter
- 클래스 타입: 객체 또는
HashMap
- 미디어 타입:
application/json
관련 - 응답시 미디어 타입:
application/json
관련
- 클래스 타입: 객체 또는
ArgumentResolver와 ReturnValueHandler
애노테이션 기반 컨트롤러가 매우 다양한 파라미터를 사용할 수 있는 이유는 ArgumentResolver 이다.
- 애노테이션 기반 컨트롤러를 처리하는
RequestMappingHandlerAdaptor
가HandlerMethodArgumentResolver
를 호출해서 컨트롤러(핸들러)가 필요로하는 다양한 파라미터의 값(객체)을 생성한다. 파라미터의 값이 모두 준비되면 컨트롤러를 호출하면서 값을 넘겨준다. - 스프링은 30개가 넘는 ArgumentResolver를 기본으로 제공한다. [https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-annarguments]
public interface HandlerMethodArgumentResolver {
boolean supportsParameter(MethodParameter parameter);
@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}
- 동작방식 : ArgumentResolver의
suppoertsParameter()
를 호출해서 해당 파라미터를 지원하는지 체크한다. 지원하면resolveArgument()
를 호출해서 실제 객체를 생성하고, 이 객체는 컨트롤러 호출시 넘어간다.- 이 인터페이스를 확장해서 원하는 ArgumentResolver를 만들 수도 있다.
기능확장은 생략 (WebMvcConfigurer 상속)
반대로 응답 값을 변환하고 처리하는 것은 ReturnValueHandler 이다. ModelView로 반환하든 String으로 반환하든 동작하는 이유가 이것 덕분이다.
- 애노테이션 기반 컨트롤러가
HandlerMethodReturnValueHandler
를 호출해서 조건에 맞는 응답 데이터를 HTTP 메시지에 입력한다. - 스프링은 10여개가 넘는 ReturnValueHandler를 지원한다. [https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-annreturn-types]
HttpMessageConverter가 사용되는 위치
HttpMessageConverter
를 사용하는 @RequestBody
나 @ResponseBody
는 각각 컨트롤러가 필요로 하는 파라미터 값, 반환 값에 사용된다. 따라서
- 요청의 경우
@RequestBody
나HttpEntity
를 처리하는 ArgumentResolver가HttpMessageConverter
를 사용해서 필요한 객체를 생성한다. - 응답의 경우
@ResponseBody
나HttpEntity
를 처리하는 ArgumentResolver가HttpMessageConverter
를 사용해서 응답결과를 생성한다.
'Web > Spring' 카테고리의 다른 글
DAO, DTO, VO, Repository, 뭐가 다른걸까? (0) | 2022.06.07 |
---|---|
[Inflearn] 스프링 MVC (8) 웹 페이지 만들기 (0) | 2022.03.07 |
[Inflearn] 스프링 MVC (6) HTTP 응답 (0) | 2022.01.31 |
[Inflearn] 스프링 MVC (5) HTTP 요청 (0) | 2022.01.28 |
[Inflearn] 스프링 MVC (4) 요청 매핑 (0) | 2022.01.28 |