我使用RestTemplate
与多个REST服务进行交互,其中一些服务接受/返回JSON和一些XML。为此,我添加了Jackson's dataformat-xml module作为依赖项(以及JAXB annotations module)。 RestTemplate
自动包含MappingJackson2XmlHttpMessageConverter
(在RestTemplate
构造函数中完成)。
这会产生一种情况,其中某些对象在调用
时用作request
参数
RestTemplate.postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)`
将serlialized作为XML,并将请求的内容类型设置为application/xml
。例如:
MyObject request = ...;
String url = ...;
MyResponseObject response = restTemplate.postForObject(url, request, MyResponseObject.class);
RestTemplate
尝试将MyObject
序列化为XML,并将请求媒体类型设置为application/xml
。
问题是,我们称之为的许多服务都不接受XML(他们期望JSON)。所以现在我在类路径上有MappingJackson2XmlHttpMessageConverter
,它优先于JSON转换器,这使得对JSON服务的调用失败。
我想我可以改变我的调用代码来传递一个HttpEntity
,其媒体类型显式设置为JSON而不是我的简单数据对象,但那种丑陋(样板)并且意味着改变相当多的服务呼叫代码。
有没有办法
A)更改MessageConverters的优先级,使标准Jackons(JSON)优先于MappingJackson2XmlHttpMessageConverter
或
B)阻止MappingJackson2XmlHttpMessageConverter
声称它可以序列化我不想要的对象
答案 0 :(得分:1)
我可以看到两个选项:
使用您想要的HttpMessageConverter创建一个RestTemplate
,按照您希望它们使用的顺序(检查HttpEntityRequestCallback.doWithRequest
它们按照它们在列表中的顺序使用,第一个<将使用em>匹配转换器
根据您的建议,使用HttpEntity
并将Content-Type
标头设置为您想要的mime类型。
我认为使用助手创建一个带有您对象的HttpEntity
并且正确的Content-Type标头会更安全:
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);
}
}