IT

메시지 컨버터의 종류

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

ByteArrayHttpMessageConverter

지원하는 오브젝트 타입은 byte[] 이다. 미디어 타입은 모든 것을 다 지원한다. 따라서 @RequestBody 로 전달받을 때는 모든 종류의 HTTP 요청 메시지 본문을 byte 배열로 가져올 수 있다. 반대로 @ResponseBody 로 보낼 때는 콘텐트 타입이 application/octet-stream 으로 설정된다. 컨트롤러가 byte 배열에 담긴 바이너리 정보를 클라이언트에 전송할 필요가 있을 때 외에는 그다지 유용해 보이지 않는다. 바이너리 포맷을 가진 정보를 주고 받아야 하는 시스템이 있다면 활용할 수 있을 것이다.

StringHttpMessageConverter

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

XML 이나 JSON 같은 공개된 형식 외에 직접 정의한 문서 포멧이 있다면 적절한 파서를 붙여서 활용할 수 있도록 문자열로 받는 것이 편리하다. 물론 좀 더 나은 방법은 해당 문서 포멧을 지원하는 HttpMessageConverter 를 직접 개발해서 적용하는 것이다.

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

FormHttpMessageConverter

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

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

SourceHttpMessageConverter

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

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

Jaxb2RootElementHttpMessageConverter

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

JAXB2의 스키마 컴파일러를 통해 생성된 바인딩용 클래스를 이용해서 손쉽게 XML 과 오브젝트 사이의 변환 기능을 이용할 수 있다. JAXB2에 숙련된 개발자라면 이를 이용해 편리하게 XML 문서 기반의 컨트롤러를 만들 수 있다.

MarshallingHttpMessageConverter

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

MappingJacksonHttpMessageConverter

Jackson ObjectMapper 를 이용해서 자바 오브젝트와 JSON 문서를 자동변환해주는 메시지 컨버터다. 지원 미디어 타입은 application/json 이다. 자바 오브젝트 타입에 제한은 없지만 프로퍼티를 가진 자바빈 스트일이거나 HashMap 을 이용해야 정확한 변환 결과를 얻을 수 있다.

Jackson 프로젝트의 ObjectMapper 가 대부분의 자바 타입을 무난히 JSON 으로 변환해주지만 날짜나 숫자 등에서 포맷을 적용하는 등의 부가적인 변환 기능이 필요하다면 ObjectMapper 를 확장해서 적용할 수 있다. 스프링 소스가 제공하는 MVC-AJAX 예제 프로젝트(https://src.springsource.org/svn/spring-samples/mvc-ajax/trunk) 를 보면, 스프링의 컨버전 서비스를 JSON 변환에 적용하도록 ObjectMapper 를 확장한 예를 찾아 볼 수 있다.

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

 

Posted by sinpk