Reputation: 32914
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
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