小小涉及OpenFeign原理:Could not extract response: no suitable HttpMessageConverter found for response type
一、问题解释(想看总结的去最下面)org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class XXX] and content type [XXX;XXX]
一、问题解释(想看总结的去最下面)
org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class XXX] and content type [XXX;XXX]
凡是报这个错误,翻译成人话就是
没有一个自带的转换器能把[class XXX]转换成content type [XXX;XXX]
二、问题解决
例如我这个项目,技术栈是nacos+openfeign+springboot+springcloud
我是在feign远程调用那会报错的。
情形一:
以 content type[text/html;charset=utf-8] 为例子
可以自行建立一个config包,在config包下写下MyRestTemplate类即可:
@Bean("restTemplate")
public RestTemplate restTemplate(){
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(
MediaType.TEXT_HTML, //配了text/html
MediaType.TEXT_PLAIN)); //配了 text/plain
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
return restTemplate;
}
//类上面记得加@configuration
情形二:(有说到feign原理,恳请大家认真理解谢谢)
说在最前面!!!!!!!!!!!!
也许看完之后你发现你的问题和我的表面上完全不一样,但是我说的是思路,还是希望能帮到各位,可以自己去debug再试试哦,莫慌莫慌
开始:结合我个人经历去看,我debug了很久发现了一些问题
1.首先我有一个过滤器,过滤器会帮我过滤掉那些没登录就想请求私密领域的请求
2.其次我debug了一下feign源码,我发现feign自动帮我用RequestTemplate这个类来帮我重新构造一个请求
换句话说,但凡调用远程方法,feign都会“没事干”地重新搞出一个新请求
3.然后我debug把远程调用的报错那块try catch得到了标题这个报错
4.这个时候别急,先去浏览器自己把完整url写好,在浏览器自己调用一下报错的那个远程方法,这个时候我的拦截器出场了,如下图:
语句1,我注释了,但是没测试过注释了行不行
语句2,我直接去访问那个页面的时候跳了这个报告,报告这个东西的原因是我的拦截器把这个请求拦截了,因为没登录
我现在大概知道为什么了
解释:
在远程调用方法的时候,feign是会重构造请求的,而feign重构造请求会丢失请求头和丢失上下文(这个可以百度,相当于常识),换句话说,就算你登录了,远程调用的时候由于丢失了session,系统也会判断你没登录。
于是!
注意!!!!!!!!!!
原本被调用的那个方法应该给我返回一个[application/json]这种类型的数据
但是你可能因为没登录,也就是没调到那个接口,他给你重定向去了首页,返回的类型不是[application/json],而有可能是下图这种奇怪类型
恰好feign又没有办法解析这种类型,于是报错!!
我想我应该说明白了吧…是吧?(笑)
我解决问题比较暴力,如下图:
当匹配到这个路径(也就是报错的那个服务的url路径)的时候,我直接返回true,也就是默认他已经登录,然后再启动服务,发现这次就没报错了。
总结
检查 content type [XXX;XXX] 到底是不是你要的,比如你希望得到 content type [application/json] 但是实际上却不是。
如果不是你想要的,你就得看看你的其他远程服务会不会报同样的错,如果没有报错,说明是个别问题,需要你详细看上面的情形二,找找灵感。如果是普适错误,说明你可能有其他问题…
如果是你想要的,那我觉得你去看看情形一吧,看看加上这个类有没有用…
更多推荐
所有评论(0)