首页 > 解决方案 > Spring:RestTemplate:无法提取响应:没有合适的 HttpMessageConverter

问题描述

我已经知道有关 StackOverflow 上存在类似问题的多个帖子,并且我也浏览了一些帖子并试图解决我的问题但面临其他问题。我将介绍我的实现并解释面临的挑战。请指导我。

请求标头'Content-Type: application/json','Accept: "text/html,application/xml;q=0.9,application/xhtml+xml,text/xml;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5,application/json;charset=UTF-8"

API调用ResponseEntity<String> responseEntity = restTemplate.exchange(url, method, httpEntity, String.class, paramMap);

响应 APIContent-Type: application/json

  1. 最初,我遇到了异常,并在 SO 上浏览了多个帖子并实施了这个解决方案: 异常org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class java.lang.String] and content type [application/json]
    实施完成

RestTemplate restTemplate = new RestTemplate();

MappingJackson2HttpMessageConverter jackson2Converter = new MappingJackson2HttpMessageConverter(); 
jackson2Converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL)); 
List<HttpMessageConverter<?>> httpMessageConverters = restTemplate.getMessageConverters();
httpMessageConverters.add(jackson2Converter);

restTemplate.setMessageConverters(httpMessageConverters);

在此更改之后,我开始得到以下异常:

java.util.ConcurrentModificationException: null at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at org.springframework.web.client.RestTemplate$AcceptHeaderRequestCallback.doWithRequest(RestTemplate.java:730) at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:795) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:617) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:588) at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:507) at

为了解决上述问题,我做了以下更改:

requestHeaders.set("Accept", MediaType.APPLICATION_JSON_VALUE); 

RestTemplate restTemplate = getRestTemplate(); 
List<HttpMessageConverter<?>> httpMessageConverters = getHttpMessageConverters(); 
restTemplate.setMessageConverters(httpMessageConverters); 
 
ResponseEntity<String> responseEntity = restTemplate.exchange(url, method, httpEntity, String.class, paramMap); 
 
 
private List<HttpMessageConverter<?>> getHttpMessageConverters() { 
  StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(); 
  stringConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL)); 
  MappingJackson2HttpMessageConverter jackson2Converter = new MappingJackson2HttpMessageConverter(); 
  jackson2Converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL)); 
  return new ArrayList<>(Arrays.asList(jackson2Converter, stringConverter));
}

经过上述更改后,我开始出现以下异常:

Could not read document: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: java.io.PushbackInputStream@99ef5fc; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: java.io.PushbackInputStream@99ef5fc; line: 1, column: 1]","context":"default","exception":"org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: java.io.PushbackInputStream@99ef5fc; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: java.io.PushbackInputStream@99ef5fc; line: 1, column: 1]\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:227)\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:212)\n\tat org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:95)\n\tat org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:884)\n\tat org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:868)\n\tat org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:622)\n\tat org.springframework.web.client.RestTemplate.execute(RestTemplate.java:588)\n\tat org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:507)\n\tat

请让我知道,我在哪里做错了,我的理解和实施有什么差距。提前致谢!!

标签: javajsonspringhttpresponse

解决方案


默认情况下,Spring RestTemplate 将根据类路径中可用的内容为自己配置一系列 HttpMessageConverters。

https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java

由于您似乎没有在 MappingJackson2HttpMessageConverter 中使用自定义 Jackson ObjectMapper,因此您实际上不需要配置一个。事实上,您为消息转换器所做的唯一事情就是调用以下内容:

jackson2Converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL)); 

据我了解,它用于表示此消息转换器能够转换所有媒体类型(这是不正确的)。

我怀疑你真正需要的是:

RestTemplate restTemplate = getRestTemplate(); 
 
ResponseEntity<String> responseEntity = restTemplate.exchange(url, method, httpEntity, String.class, paramMap); 

但是,即使那样,它也可能不起作用,因为您在请求中提供了以下接受标准:

Accept: "text/html,application/xml;q=0.9,application/xhtml+xml,text/xml;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5,application/json;charset=UTF-8"

我会先尝试排除接受标头,如果这不起作用,我会尝试将其设置为 application/json。


推荐阅读