Table of contents
1 背景
有某一個 Spring Boot 2 既 web application 唔知點解有個 HTTP POST API 喺唔同情況下,有時會返回 JSON 或者 XML 格式既 responses,而 XML 格式就會導致 consumer application 喺 deserialize 個 response 既時候出現 deserialization exception。
情況 | Response 格式 |
---|
使用 Postman 直接 call 個 API | JSON |
喺 cloud provider 平台上面 test 個 API | JSON |
Consumer application 喺 cloud 既環境下用 Spring 既 RestTemplate call 個 API | XML |
Postman 既 call 法係用默認既 Postman HTTP request headers,Accept
request header 係 */*
。
Cloud provider 平台既 call 法係冇任何 HTTP request headers。
Consumer application 用既係 RestTemplate#exchange
method 去 call 呢個 HTTP POST API,而 HttpEntity
既 request body 係 null
,HttpHeaders
係 new HttpHeaders()
,冇咩特別。
2 原因分析
2.1 Cloud provider API 配置
Cloud provider 既平台上面冇任何配置,冇對 HTTP API response 做 conversion 或者改 request header,所以唔關 cloud config 事。
2.2 Maven dependencies
如果只係得 spring-boot-starter-web
呢個 dependency,係冇能力返回 XML 格式既。
查下 Spring 既文檔就發現到原來 producer application 以及 consumer application 都有以下既 transitive dependency:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
加左呢個 dependency 之後:
- Application 會有能力返回 XML 格式既 HTTP responses。
- 不過就唔會自動將所有 exposed 既 APIs(Spring 既 request mappings)默認返回 XML 格式。
- Application 會有能力解讀 XML 格式既 HTTP responses(但唔清楚點解 consumer application 會出現 deserialization exception)。
- 會令到我地冇特別配置既
RestTemplate
既 HTTP requests 既 Accept
request header 用左 application/xml
等等既 values,咁就會令到 producer application 傾向選擇返回 XML 格式既 HTTP responses,而咁岩 producer application 又有能力咁做。
咁就解釋到點解 Postman 以及 cloud provider 平台上面測試果陣冇得到 XML 格式既 HTTP responses。
參考資料:
3 解決方法
只需要將 RestTemplate
object 既 XML message converter 移除就可以,咁喺 call HTTP APIs 既時候,就唔會喺 Accept
request headers 裡面加入 application/xml
等等既 values。
1@Bean
2public RestTemplate restTemplate() {
3 final RestTemplate restTemplate = new RestTemplate();
4 restTemplate.getMessageConverters().removeIf(MappingJackson2XmlHttpMessageConverter.class::isInstance);
5
6 return restTemplate;
7}
參考資料: