When resttemplate is used to request restful interface, the returned JSON data will always be parsed into XML data for processing under specific circumstances, and then the error in the title will appear:
Error while extracting response for type [] and content type [application/xml;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ‘5’ (code 53) in content after ‘<‘ (malformed start element?).
at [row,col {unknown-source}]: [1,15395]; nested exception is com. fasterxml. jackson. databind. JsonMappingException: Unexpected character ‘5’ (code 53) in content after ‘<‘ (malformed start element?).
According to the error information, it seems that the response header marks the return type as [application/XML; charset = UTF-8], but the actual situation is that all the returned data is [application/JSON; charset = UTF-8].
After tracing the resttemplate source code, it is found that the instance created by new resttemplate (httprequestfactory()) will have 7 Converters:
Continue to track the exchange of the resttemplate. When performing type conversion on the response, all converters in the current instance will be iterated, and then select a converter that supports the current type for execution. Use canread to judge:
At this time, the problem is found. Under certain circumstances, the contenttype of the response header is read as “application/XML”. However, the real data at this time is still in JSON format. Therefore, if the converter for XML format is deleted, the iterator will look for the next executable converter, mappingjackson2httpmessageconverter. Or change the order of the two to reduce the priority of XML.
Solution:
1: Delete XML converter
@Bean
public RestTemplate restTemplate() {
RestTemplate template = new RestTemplate(httpRequestFactory());
// Exclude xml parsing converters to avoid parsing json data as xml
List<HttpMessageConverter<?>> collect = template.getMessageConverters().stream().filter(m -> !(m instanceof MappingJackson2XmlHttpMessageConverter)).collect(Collectors.toList());
template.setMessageConverters(collect);
return template;
}
2: Reduce XML converter priority
@Bean
public RestTemplate restTemplate() {
RestTemplate template = new RestTemplate(httpRequestFactory());
// Turn down the priority of xml parsing
int xml = 0, json = 0;
List<HttpMessageConverter<?>> messageConverters = template.getMessageConverters();
for (int i = 0; i < messageConverters.size(); i++) {
HttpMessageConverter<?> h = messageConverters.get(i);
if (h instanceof MappingJackson2XmlHttpMessageConverter) {
xml = i;
} else if (h instanceof MappingJackson2HttpMessageConverter) {
json = i;
}
}
Collections.swap(template.getMessageConverters(), xml, json);
return template;
}