UL :)
UL의 개발 블로그
UL :)
전체 방문자
오늘
어제
  • 분류 전체보기 (220)
    • 일상 (1)
    • 회고록 (7)
    • ChatGPT 아카이빙 (0)
    • PS(Java) (114)
      • 백준 (37)
      • 인프런 강의 문제 (77)
    • Web (69)
      • Spring (18)
      • JPA (7)
      • JSP (9)
      • HTML5 (12)
      • CSS (19)
      • HTTP (0)
      • 보안 (2)
    • Language (5)
      • Java (3)
      • JS (1)
      • Python (1)
    • Git, GitHub (4)
    • Settings (18)
      • IntelliJ (7)
      • Eclipse (2)
      • VSCode (3)
      • Android Studio (1)
      • VMware (2)
      • Mac (0)
    • Etc (1)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • @GetMapping
  • @PostMapping
  • HandlerMethodArgumentResolver
  • 영속성컨텍스트
  • 1차 캐시
  • ORM
  • ReturnValueHandler
  • @Column
  • HttpMessageConverter
  • EntityManagerFactory
  • consumes
  • IDENTITY 전략
  • @Table
  • @JoinColumn
  • 엔티티 매핑
  • @ManyToOne
  • @Id
  • 요청헤더
  • 영속성
  • JPA
  • TABLE 전략
  • ViewName반환
  • produces
  • SEQUENCE 전략
  • 백준
  • 정렬
  • BOJ
  • argumentresolver
  • 동일성보장
  • @RequestParam

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
UL :)

UL의 개발 블로그

[Inflearn] 스프링 MVC (7) HttpMessageConverter
Web/Spring

[Inflearn] 스프링 MVC (7) HttpMessageConverter

2022. 2. 4. 00:46

김영한 강사님의 '스프링 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 요청: read()를 호출해서 객체를 생성 및 반환
    • HTTP 응답: write()를 호출해서 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
    'Web/Spring' 카테고리의 다른 글
    • DAO, DTO, VO, Repository, 뭐가 다른걸까?
    • [Inflearn] 스프링 MVC (8) 웹 페이지 만들기
    • [Inflearn] 스프링 MVC (6) HTTP 응답
    • [Inflearn] 스프링 MVC (5) HTTP 요청
    UL :)
    UL :)
    백엔드 개발자를 목표로 달리고 있습니다🔥

    티스토리툴바