现象重现
springboot框架的项目,使用RestTemplate 远程调用 第三方的接口 报错,报错信息如下:
中文翻译一下,也就是:
无法提取响应:没有找到适合响应类型的HttpMessage转换器
抽丝剥茧,分析原因
第一步:
因为使用的是RestTemplate 来请求第三方接口,而项目中也引入了jackson的依赖,所以先下一个结论:
RestTemplate 采用的是 MappingJackson2HttpMessageConverter转换器,默认处理json类型的数据
为什么说使用的是MappingJackson2HttpMessageConverter转换器?
我们知道RestTemplate中,使用了很多的转换器,那他是如何选择的,接下来看JacksonHttpMessageConvertersConfiguration 的源码:
双击 shift 键搜索:JacksonHttpMessageConvertersConfiguration,进入该类中
由此可以看出来添加 Jackson依赖后,SpringBoot 会自动帮你运行MappingJackson2HttpMessageConverter,这个转换工具类
需要注意的是这个转换工具类实现的前提是,自己没有定义该工具类,如果自己定义了的话,会优先使用自己定义的覆盖系统自带的
第二步:
我们知道了,RestTemplate 请求接收的是json类型数据,然后我们发现第三方的接口,返回结果的数据 content-type类型 为 text/html,所以才会造成调用端无法解析,导致报错。
解决方案
改下RestTemplateConfig配置类,增加支持 text/html类型的解析
package com.hidata.devops.config; import java.util.Arrays; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { private int timeoutms = 5 * 60 *1000; @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory){ RestTemplate restTemplate = new RestTemplate(factory); MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList( MediaType.TEXT_HTML, MediaType.TEXT_PLAIN)); restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter); return restTemplate; } @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory(){ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setReadTimeout(timeoutms);//ms factory.setConnectTimeout(timeoutms);//ms return factory; } }