如何防止MappingJackson2XmlHttpMessageConverter接管序列化?
How to prevent MappingJackson2XmlHttpMessageConverter from taking over serialization?
我正在使用 RestTemplate
与几个 REST 服务交互,其中一些 accept/return JSON 和一些 XML。为此,我添加了 Jackson's dataformat-xml module as a dependency (along with the JAXB annotations module)。 RestTemplate
自动包含 MappingJackson2XmlHttpMessageConverter
(在 RestTemplate
构造函数中完成)。
这会导致一些对象在调用
时用作 request
参数
RestTemplate.postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)`
序列化为 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 服务的调用失败。
我想我可以更改我的调用代码以传递媒体类型显式设置为 JSON 的 HttpEntity
而不是我的简单数据对象,但这有点丑陋(样板)并且会意味着改变相当多的服务调用代码。
有没有办法
A) 更改 MessageConverter 的优先级,使标准 Jackons (JSON) 优先于 MappingJackson2XmlHttpMessageConverter
或
B) 防止 MappingJackson2XmlHttpMessageConverter
声称它可以序列化我不希望它序列化的对象
?
我可以看到两个选项:
用你想要的 HttpMessageConverter 创建一个 RestTemplate
,按照你希望它们使用的顺序(检查 HttpEntityRequestCallback.doWithRequest
它们按照它们在列表中的顺序使用并且将使用第一个匹配转换器
按照您的建议,使用 HttpEntity
并将 Content-Type
header 设置为您想要的 mime 类型。
我认为使用助手用你的 object 和正确的 Content-Type header 创建一个 HttpEntity
会更安全:
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);
}
}
我正在使用 RestTemplate
与几个 REST 服务交互,其中一些 accept/return JSON 和一些 XML。为此,我添加了 Jackson's dataformat-xml module as a dependency (along with the JAXB annotations module)。 RestTemplate
自动包含 MappingJackson2XmlHttpMessageConverter
(在 RestTemplate
构造函数中完成)。
这会导致一些对象在调用
时用作request
参数
RestTemplate.postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)`
序列化为 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 服务的调用失败。
我想我可以更改我的调用代码以传递媒体类型显式设置为 JSON 的 HttpEntity
而不是我的简单数据对象,但这有点丑陋(样板)并且会意味着改变相当多的服务调用代码。
有没有办法
A) 更改 MessageConverter 的优先级,使标准 Jackons (JSON) 优先于 MappingJackson2XmlHttpMessageConverter
或
B) 防止 MappingJackson2XmlHttpMessageConverter
声称它可以序列化我不希望它序列化的对象
?
我可以看到两个选项:
用你想要的 HttpMessageConverter 创建一个
RestTemplate
,按照你希望它们使用的顺序(检查HttpEntityRequestCallback.doWithRequest
它们按照它们在列表中的顺序使用并且将使用第一个匹配转换器按照您的建议,使用
HttpEntity
并将Content-Type
header 设置为您想要的 mime 类型。
我认为使用助手用你的 object 和正确的 Content-Type header 创建一个 HttpEntity
会更安全:
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);
}
}