E-Riz
E-Riz

Reputation: 32914

How to prevent MappingJackson2XmlHttpMessageConverter from taking over serialization?

I'm using RestTemplate to interact with several REST services, some of them accept/return JSON and some XML. To that end, I've added Jackson's dataformat-xml module as a dependency (along with the JAXB annotations module). RestTemplate automatically includes MappingJackson2XmlHttpMessageConverter (done in the RestTemplate constructor).

This creates a situation where some objects that are used as the request parameter in calls to

RestTemplate.postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)`

get serlialized as XML and the content-type of the request is set to application/xml. For example:

MyObject request = ...;
String url = ...;
MyResponseObject response = restTemplate.postForObject(url, request, MyResponseObject.class);

RestTemplate tries to serialize MyObject to XML and sets the request media type to application/xml.

Problem is, many of the services we call don't accept XML (they expect JSON). So now that I have MappingJackson2XmlHttpMessageConverter on the classpath, it's taking precedence over the JSON converter which makes the calls to JSON services fail.

I suppose I could change my calling code to pass an HttpEntity with the media type explicitly set to JSON instead of my simple data object, but that's kind of ugly (boilerplate) and would mean changing quite a few service calling code.

Is there a way to either

A) change the priority of the MessageConverters so that the standard Jackons (JSON) one takes priority over MappingJackson2XmlHttpMessageConverter

or

B) Prevent MappingJackson2XmlHttpMessageConverter from claiming that it can serialize the objects I don't want it to

?

Upvotes: 2

Views: 4093

Answers (1)

Alexandre Jacob
Alexandre Jacob

Reputation: 3041

I can see two options :

  • Create a RestTemplate with the HttpMessageConverter you want, in the order you want them to be used (check HttpEntityRequestCallback.doWithRequest they are used in the order they are in the list and the first matching converter will be used

  • As you suggested, using an HttpEntity and setting the Content-Type header to the mime type you want to get.

I think using a helper to create an HttpEntity with your object and the correct Content-Type header would be safer :

public class HttpEntityHelper {

    public static <T> HttpEntity<T> jsonHttpEntity(T body) {
        MultiValueMap<String, String> headers = new LinkedMultiValueMap();
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        return new HttpEntity(body, headers);
    }
}

Upvotes: 2

Related Questions