본문 바로가기
Spring Framework/Spring

WebMvcConfigurer

by devstep 2022. 4. 18.

org.springframework.web.servlet.config.annotation.WebMvcConfigurer

WebMvcConfigurer

스프링프레임워크에서 제공하는 config 관련 interface이다.

구현클래스

WebMvcConfigurerAdapter

  • deprecate 되었다.
  • 이유 알아보기

공부했던 이유

  • 메세지 컨버터, objecMappter에 대해 알아보고 싶었다.
  • API request, response 속성들의 데이터 타입이라던지, 속성의 맵핑 시, 잘 되지 않았을 때 무엇을 봐야 하고 해결을 해나가기 위해 공부하고 싶었다.
  • 공부해보니 스프링의 동작원리를 알아야 했으며 그래서 키워드로 검색해 이해하기엔 한계가 있었다.
  • 그래도 토비의 스프링은 설명이 워낙 자세해서 제일 유용한 자료였다.

WebMvcConfigurer을 구현함으로써 Application의 어떤 변화가 있는지 알아보기

@EnableWebMvc

  • WebMvcConfigurer를 반드시 @EnableWebMvc 어노테이션과 함께 사용해야할 필요는 없다.
  • SpringMVC의 자바코드 기반 환경 설정을 커스텀 하기 위한 콜백 메서드 정의
  • 기본 환경 설정 파일을 커스텀하고 call back 하기 위해 @EnableWebMvc 애노테이션이 붙은 클래스는 WebMvcConfigurer 인터페이스를 구현해야 한다.
  • @EnableWebMvc를 사용하면 ViewResolver 값이 자동으로 등록된다.

일반적으로 WebMvcConfigurer은 WebConfig와 같은 Config 파일에서 사용된다.
여기서 WebConfig 파일의 존재 목적은 다음과 같다.
DispactcherServlet을 생성할 때생성자 인자로 WebApplicationContext을 전달한다.
그런데 WebApplicationContext은 어떤 Config 파일을 사용할 지 명시해줘야 하는데 그 Config 값으로 일반적으로는 WebConfig를 지정한다.

만약 위 문장이 이해가 가지 않는다면 반드시 DispatcherServlet가 WebApplicationContext를 생성하는 2가지 방법 찾아보기

WebMvcConfigurer이 하는 일

  • WebMvcConfigurer – which will allow us to change the default list of Http Converters with our own.
  • 클라언트가 지정한 " Accept " 헤더는 엔티티를 마샬링할 적절한 Http Converter를 선택하는 데 사용됩니다.

Spring’s RestTemplate With HTTP Message Converters

서버 측과 마찬가지로 HTTP 메시지 변환은 Spring RestTemplate 의 클라이언트 측에서 구성할 수 있습니다 .

적절한 경우 AcceptContent-Type 헤더 를 사용하여 템플릿을 구성할 것 입니다. 그런 다음 JSON 및 XML 모두 에서 Foo 리소스 의 전체 마샬링 및 비정렬화와 함께 REST API를 사용하려고 합니다 .

Accept Header가 없는 리소스 검색

@Test
public void whenRetrievingAFoo_thenCorrect() {
    String URI = BASE_URI + "foos/{id}";

    RestTemplate restTemplate = new RestTemplate();
    Foo resource = restTemplate.getForObject(URI, Foo.class, "1");

    assertThat(resource, notNullValue());
}

토비의 스프링에서 말하는 MessageConverter

  • 메시지 컨버터는 XML이나 JSON을 이용한 AJAX 기능이나 웹 서비스를 개발할 때
    시용할 수 있다.
  • HTTP 요청 프로퍼티를 모델 오브젝트의 프로퍼티에 개별적으로 바인딩하고 모델 오브젝트를 다시 뷰를 이용해 클라이언트로 보낼 콘텐트로 만드는 대신
  • HTTP 요청 메시지 본문과 HTTP 응답 메시지 본문을 통째로 메시지로 다루는 방식이다.
  • 메시지 컨버터는 파라미터의 @RequestBody와 메소드에 부여한 @ResponseBody를 이용해서쓸수있다.

메세지 컨버터 종류(defaultHttpMessageConverters)

  • 일반적으로 하나 이상의 메시지 컨버터를 등록해두고 요청 타입이나 오브젝트 타입에 따라 선택되게한다.
  • AnnotationMethodHandlerAdapter에 등록되는 디폴트 메시지 컨버터는 다음과 같다.
  1. ByteArrayHttpMessageConverter : 바이너리 포맷을 가진 정보를 주고받아야 하는 시스템에서 활용
  2. StringHttpMessageConverter : HTTP 요청의 본문을 그대로 스트링으로 가져올 수 있다
    • HTTP가 기본적으로 텍스트 기반의 포맷이므로 가공하지 않은 본문을 직접 받아서 사용하고 싶은 경우라면 유용하게 쓸 수 있다.
      • 응답의 경우는 콘텐트 타입이 text/plain으로 전달된다. 단순 문자열로 응답을 보내고 싶을 때 @ResponseBody와 함께 스트링 리턴 값을 사용하면 된댜
  3. FormHttpMessageConverter : application/x-www-form-urlencoded로 정의된 폼 데이터를 주고 받을 때 사용
    • 오브젝트 타입은 다중 값을 갖는 맵 확장 인터페이스인 MultiValueMap〈String, String〉을 지원
  4. SourceHttpMessageConverter
  • 디폴트로 등록되지 않은 HttpMessageConverter
  • 디폴트 메세지 컨버터보다 실제로 더 유용하다.
  • 사용하기 위해서는 직접 AnnotationMethodHandlerAdapter 빈의 messageConverters 프로퍼티에 등록하고 사용해야 한다.
  1. Jaxb2RootElementHttpMessageConverter
    • JAXB2의 @XmlRootElement와 @XmlType이 붙은 클래스를 이용해서 XML과 오브젝트 사이의 메시지 변환을 지원
  2. MarshallingHttpMessageConverter
    • 스프링 OXM 추상화의 Marshaller와 Unmarshaller를 이용해서 XML 문서와 자바 오브젝트 사이의 변환을 지원해주는 컨버터
  3. MappingJacksonHttpMessageConverter
    • Jackson Obj ectMapper를 이용해서 자바오브젝트와 JSON 문서를 자동변환해주는 메시지 컨버터다.
      • 프로젝트에서 해당 메세지컨버터를 사용하지 않았지만 자동으로 json문서로 to/from 자동변환 되었다. 왜일까?
      • 지원 미디어 타입은 application/json
      • 자바오브젝트 타입에 제한은 없지만 프로퍼티를 가진 자바빈 스타일이거나 HashMap을 이용해야 정확한 변환결과를 얻을 수 있다.
      • Jackson 프로젝트의 ObjectMapper가 대부분의 자바 타입을 무난히 JSON으로 변환해주지만 날짜나 숫자 등에서 포맷을 적용하는 등의 부가적인 변환 기능이 필요하다면 ObjectMapper를 확장해서 적용할 수 있다

사용법

위의 3가지의 메세지컨버터를 사용하려면 리스트 4-109와 같이
AnnotationMethodHandlerAdapter 빈을 등록하고 messageConverters 프로퍼티에 등록해줘야 한다. 여타 전략과 마찬가지로 전략 프로퍼티롤 직접 등록하면 디폴트 전략은 자동으로 추가되지 않는다는 점을 주의하자.

궁금한 사항

  • 그러면 메세지 컨버터를 지정하지 않을 경우, 기본으로 어떤 메세지 컨버터를 사용했을까?

defaultHttpMessageConverters, MappingJackson2HttpMessageConverter

  • MappingJackson2HttpMessageConverter
  • application/json 처리
  • 클래스 타입: 객체 또는 HashMap
  • 미디어 타입: application/json
  • HTTP 요청 예시: @RequestBody Example example
  • HTTP 응답 예시: @ResponseBody return example (쓰기 MediaType: application/json)

참고 자료


함께 공부할 것

Argument Resolver

  • Controller로 들어온 파라미터를 가공하거나 수정 기능을 제공하는 객체
  • Controller에서 argument resolver를 사용하면 중복코드를 깔끔하게 처리할 수 있다.
  • 예제가 있는 블로그 글만 읽고 이해하기로는, cotroller method에 argument에 HTTP Request 관련 정보를 맵핑해주는 것 같다.

Spring에서 Resolver의 동작 과정

  1. Client Request 요청
  2. Dispatcher Servlet에서 해당 요청 처리
  3. Client Request에 대한 Handler Mapping
    3.1 RequestMapping에 대한 매칭 (RequestMappingHandlerAdapter가 수행)
    3.2 Interceptor 처리
    3.3 Argument Resolver 처리 <-- Argument Resolver 실행 지점
    3.4 Message Converter 처리
  4. Controller Method invoke

정리하면 특정 Request가 Handler로 Mapping되는 과정에서 invoke 되기 전,Interceptor > Resolver > MessageConverter 순으로 처리된 후, Controller의 Method가 invoke 된다.

댓글