java - 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);
响应 API:Content-Type: application/json
- 最初,我遇到了异常,并在 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
请让我知道,我在哪里做错了,我的理解和实施有什么差距。提前致谢!!
解决方案
默认情况下,Spring RestTemplate 将根据类路径中可用的内容为自己配置一系列 HttpMessageConverters。
由于您似乎没有在 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。
推荐阅读
- angular - 当列中有 *ngIf 时,mat-table 中的 ExpressionChangedAfterItHasBeenCheckedError
- javascript - 带有Greensock JS钩子的Vue列表动画:等待离开完成后再进入
- javafx - 如何在 JavaFX 画布中绘制带下划线的文本
- app-inventor - 是否可以在 MIT App Inventor 上编写能够在后台运行的应用程序?
- reactjs - 如何将具有 html 标签的道具内容转换为 html 并将其显示而不是显示为字符串?
- javascript - 在站点地图中指定规则时使用的这个符号 /\ 是什么
- java - 在一组对象中查找连续的字符串属性序列(通过流 API)
- python - 在python方法中将自己的类对象作为参数传递
- ios - UIPageViewController - 改变点不起作用
- android - 由于未就 Android 许可证达成一致,通过 TFS 运行的 Gradle 构建失败