티스토리 뷰

반응형

요즘 뭐 하기도 싫고 번아웃이 온거 같다. 그러던 중 지하철에서 예전에 완강했던 백기선님의 '스프링부트의 개념과 활용'을 다시 볼 기회가 있었고, 그 중 HttpMessageConverters에 관해서 다시 듣게 되었다. 최근 진행했던 토이프로젝트에서 @ResponseBody를 이용하여  String 타입으로 Json으로 리턴하도록 만든 부분이 있었는데, 뭐가 문제였는지 계속 Json으로 Return이되지 않아서 그냥 Map을 사용해서 완성했었다. 이강의를 다시 보게 되니.. 그때 왜 Json으로 리턴되지 않았는지 알 수 있었다..@ResponseBody를 사용하여 String과 Int로 리턴할 때는 자동으로 StringHttpMessageConverter가 사용된다.  객체를 리턴할 때는 JsonMessageConverter로.. 하.. 강의를 들을 당시에는 별 생각없이 빨리 듣고자 하는 마음이 앞서서 제대로 안들었나보다. 기회가 생길 때 다시 정주행 해야 겠다.


아래는 토비의 스프링3.1에서 메시지 컨버터에 대해 적혀 있는 내용과 스프링부트의 개념과 활용에 나온 내용을 정리한 부분이다.

 

...더보기

HttpMessageConverter는 스프링 프레임워크에서 제공하는 인터페이스 이다. 스프링 MVC의 일부분으로 Http를 이용한 요청과 응답시에 알아서 컨텐츠 타입과 본문을 봐서 컨버젼 해준다. 그 중 우리가 어떤 요청을 하는지에 따라 사용하는 컨버터가 다르다.

 

메세지 컨버터는 XML이나 JSON을 이용한 AJAX 기능이나 웹 서비스를 개발할 때 사용할 수 있다. 

HTTP 요청 프로퍼티를 모델 오브젝트의 프로퍼티에 개별적으로 바인딩하고 모델 오브젝트를 다시 뷰를 이용해 클라이언트로 보낼 콘텐트로 만드는 대신 HTTP 요청 메시지 본문과 HTTP 응답 메시지 본문을 통째로 메시지로 다루는 방식이다.

메시지 컨버터는 파라미터의 @RequestBody와 @ResponseBody를 이용해서 쓸 수 있다.

HTTP 요청 본문을 객체로 변경하거나(@RequestBody),
객체를 HTTP 응답 본문으로 변경(@ResponseBody)할 때 사용.
{“username”:”055055”, “password”:”123”} <-> User

 

메시지 방식의 컨트롤러를 사용하는 방법은 두 가지로 구분한다. HTTP 요청 메소드에 따라서 GET과 POST로 나누는 것이다. GET의 경우는 요청 정보가 URL과 쿼리 스트링으로 제한되므로 @RequestBody를 사용하는 대신 @RequestParam이나 @ModelAttribute로 요청 파라미터를 전달 받는다. 반면에 POST의 경우라면 HTTP요청 본문이 제공되므로 @ReqeustBody를 사용할 수 있다.

 

RequestBody  사용할 떄는

Getter, Setter 있어야 한다. 자바 빈 규약에 따라서 Getter, Setter 의해 바인딩 해준다.

 

메시지 컨버터의 종류

사용할 메시지 컨버터는 AnnotaionMethodHandlerAdapter를 통해 등록한다. 일반적으로 하나 이상의 메시지 컨버터를 등록해두고 요청 타입이나 오브젝트 타입에 따라 선택되게 한다. AnnotaionMethodHandlerAdapter에 등록되는 디폴트 메시지 컨버터는 다음과 같다.

 

1. ByteArrayHttpMessageConverter

지원하는 오브젝트 타입은 byte[]이다. 미디어 타입은 모든 것을 다 지원한다. 따라서 @RequestBody로 전달 받을 때는 모든 종류의 HTTP요청 메시지 본문을 byte 배열로 가져올 수 있다. 반대로 @ResponseBody로 보낼 때는 콘텐트 타입이 application/octet-stream으로 설정된다. 

 

2. StringHttpMessageConverter

지원하는 오브젝트 타입은 String이다. 미디어 타입은 모든 종류를 다 허용한다. 따라서 HTTP 요청의 본문을 그대로 스트링으로 가져올 수 있다. HTTP가 기본적으로 텍스트 기반의 포맷이므로 가공하지 않은 본문을 직접 받아서 사용하고 싶은 경우 유용할 수 있다.

응답의 경우는 콘텐트 타입이 text/plain으로 전달 된다. 단순 문자열로 응답을 보내고 싶을 때 @ResponseBody와 함께 String 리턴 값을 사용하면 된다.

 

3. FormHttpMessageConverter

미디어 타입이 application/x-www-form-urlencoded로 정의된 폼 데이터를 주고 받을 때 사용할 수 있다. 오브젝트 타입은 다중 값을 갖는 맵 확장 인터페이스인 MultiValueMap<String, String>을 지원한다. MultiValueMap은 맵의 값이 List 타입인 맵으로, 하나의 이름을 가진 여러 개의 파라미터가 사용될 수 있는 HTTP 요청 파라미터를 처리하기에 적당하다. HTTP 요청의 폼 정보는 @ModelAttribute를 이용해 바인딩 하는 것이 훨씬 편리하고 유용하므로, @RequestBody에 사용할 일은 별로 없을 것이다. 

응답의 경우는 드물지만 클라이언트가 application/x-www-form-urlencoded 타입의 폼 정보를 선호한다면 이용할 수 있을 것이다.

 

4. SourceHttpMessageConverter

미디어 타입은 application/xml, application/*+xml, text/xml 세 가지를 지원한다. 오브젝트 타입은 javax.xml.transform.Source타입인 DOMSource, SAXSource, StreamSource 세 가지를 지원한다. XML문서를 Sourcr타입의 오브젝트로 전환하고자 할 때 유용할 수 있다. 그러나 최근에는 OXM 기술의 발달로 XML을 바로 자바 오브젝트로 변환하는 경우가 많기 때문에 그다지 많이 쓰이지 않겠지만 DOM이나 SAX방식의 XML 문서 접근을 선용한다면 이용할 만 한다.

 

기본적으로 위 네 가지 종류의 HttpMessageConverter가 디폴트로 등록되지만, 이보다는 디폴트로 등록되지 않은 다음 세 가지 HttpMessageConverter가 실제로 더 유용하다.  이중에서 필요한 메시지 컨버터가 있다면 직접 AnnotationMethodHandlerAdapter빈의 messageConverters 프로퍼티에 등록하고 사용해야 한다.

 

1.Jaxb2RootElementHttpMessageConverter

JAXB2의 @XmlRootElement와 @XmlType이 붙은 클래스를 이용해서 XML과 오브젝트 사이의 메시지 변환을 지원한다. 기본적으로 SourcehttpMessageConverter와 동일한 XML 미디어 타입을 지원하다. 오브젝트는 두 가지 에노테이션 중 하나가 적용됐다면 어떤 타입이든 사용할 수 있다.

 

2.MarshallingHttpMessageConverter

스프링 OXM 추상화의 Marshaller와 Unmarshaller를 이용해서 XML 문서와 자바 오브젝트 사이의 변환을 지원해주는 컨버터다.

MarshallingHttpMessageConverter를 빈으로 등록할 때 프로퍼티에 marshaller와 unmarshaller를 설정해줘야 한다. 미디어 타입은 다른 XML 기반 메시지 컨버터와 동일하며, 지원 오브젝트는 unmarshaller의 supports()메소드를 호출해서 판단한다. OXM 기술을 자유롭게 선택해서 XML 문서 기반의 컨트롤러를 작성하려고 한다면 편리하게 이용할 수 있다.

 

3.MappingJacksonHttpMessageConverter

Jackson ObjectMappter를 이용해서 자바 오브젝트와 JSON 문서를 자동 변환해주는 메시지 컨버터다. 지원 미디어 타입은 application/json이다. 자바 오브젝트 타입에 제한은 없지만 프로퍼티를 가진 자바빈 스타일이거나 HashMap을 이용해야 정확한 변환 결과를 얻을 수 있다. Jackson 프로젝트의 ObjectMapper가 대부분의 자바 타입을 무난히 JSON으로 변환해주지만 날짜나 숫자 등에서 포맷을 적용하는 등의 부가적인 변환 기능이 필요하다면 ObjectMapper를 확장해서 적용할 수 있다. 

 

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

 

Spring 5 

 

By default, the following HttpMessageConverters instances are pre-enabled:

  • ByteArrayHttpMessageConverter – converts byte arrays
  • StringHttpMessageConverter – converts Strings
  • ResourceHttpMessageConverter – converts org.springframework.core.io.Resource for any type of octet stream
  • SourceHttpMessageConverter – converts javax.xml.transform.Source
  • FormHttpMessageConverter – converts form data to/from a MultiValueMap<String, String>.
  • Jaxb2RootElementHttpMessageConverter – converts Java objects to/from XML (added only if JAXB2 is present on the classpath)
  • MappingJackson2HttpMessageConverter – converts JSON (added only if Jackson 2 is present on the classpath)
  • MappingJacksonHttpMessageConverter – converts JSON (added only if Jackson is present on the classpath)
  • AtomFeedHttpMessageConverter – converts Atom feeds (added only if Rome is present on the classpath)
  • RssChannelHttpMessageConverter – converts RSS feeds (added only if Rome is present on the classpath)

Spring5에서는 Jaxb2RootElementHttpMessageConverter , MappingJackson2HttpMessageConverter , MappingJacksonHttpMessageConverter , AtomFeedHttpMessageConverter, RssChannelHttpMessageConverter 컨버터를 사용하려면 클래스 패스에 해당 라이브러리가 있으면 자동으로 등록된다. 

 

커스터마이징이 필요하다면 @EnableWebMvc를통해 WebMvcConfigurer를 implements하여 기본 설정을 바꿀 수 있다.

 

@EnableWebMvc
@Configuration
@ComponentScan({ "com.baeldung.web" })
public class WebConfig implements WebMvcConfigurer {
 
    @Override
    public void configureMessageConverters(
      List<HttpMessageConverter<?>> converters) {
     
        messageConverters.add(createXmlHttpMessageConverter());
        messageConverters.add(new MappingJackson2HttpMessageConverter());
    }
    private HttpMessageConverter<Object> createXmlHttpMessageConverter() {
        MarshallingHttpMessageConverter xmlConverter = 
          new MarshallingHttpMessageConverter();
 
        XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
        xmlConverter.setMarshaller(xstreamMarshaller);
        xmlConverter.setUnmarshaller(xstreamMarshaller);
 
        return xmlConverter;
    }
}

 

SpringBoot2

Springboot는 Jackson library가 포함되어 있어서 자동으로 MappingJackson2HttpMessageConverter를 사용하여 JSON으로 변환해 줄 수 있다. 

 

밑에 참고한 부분에 대한 해석이 맞는지 잘 모르겠으나,  Spring Boot를 사용하여 커스터마이징하려면  WebMvcConfigurer는 implement할 필요가 없다. HttpMessageConverter beans를 선언만 해주면 된다.

 

4.1. Spring Boot Support
If we’re using Spring Boot we can avoid implementing the WebMvcConfigurer and 
adding all the Message Converters manually as we did above.

We can just define different HttpMessageConverter beans in the context, 
and Spring Boot will add them automatically to the autoconfiguration that it creates:

@Bean
public HttpMessageConverter<Object> createXmlHttpMessageConverter() {
    MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
 
    // ...
 
    return xmlConverter;
}

 

 

 

 

 

출처

토비의 스프링 3.1 Vol2 : 4.5 메시지 컨버터와 AJAX  - 이일민

스프링부트의 개념과 활용 : 스프링 웹 MVC 2부: HttpMessageConverters - 백기선

https://www.baeldung.com/spring-httpmessageconverter-rest

 

Http Message Converters with the Spring Framework | Baeldung

How to configure HttpMessageConverters for a REST API with Spring, and how to use these converters with the RestTemplate.

www.baeldung.com

https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-message-converters

 

29. Developing Web Applications

The Spring Web MVC framework (often referred to as simply “Spring MVC”) is a rich “model view controller” web framework. Spring MVC lets you create special @Controller or @RestController beans to handle incoming HTTP requests. Methods in your controller ar

docs.spring.io

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함