发送请求开始
-----[channelfeign#formrecog] ---> end http (304117-byte body)
发送请求结束
返回开始
[channelfeign#formrecog] <--- http/1.1 200 ok (4948ms)[channelfeign#formrecog] content-length: 5207[channelfeign#formrecog] content-type: text/json;chart=utf-8[channelfeign#formrecog] date: mon, 08 oct 2018 10:47:03 gmt[channelfeign#formrecog] x-vcap-request-id: c323f65a-12e6-4604-7393-a4bf0ca403d5[channelfeign#formrecog][channelfeign#formrecog] {json格式的数据}[channelfeign#formrecog] <--- end http (5207-byte body)
返回结束
error org.apache.catalina.core.containerba.[tomcat].[localhost].[/].[dispatcherrvlet] : rvlet.rvice() for rvlet [dispatcherrvlet] in context with path [] threw exception [request processing failed; nested exception is feign.codec.decodeexception: could not extract respon: no suitable httpmessageconverter found for respon type [channel.domain.channelrespon<tabledata>] and content type [text/json;chart=utf-紫鸭拓草8]] with root cau
org.springframework.web.client.restclientexception: could not extract respon: no suitable httpmessageconverter found for respon type [channel.domain.channelrespon<tabledata>] and content type [text/json;chart=utf-8]
at org.springframework.web.client.httpmessageconverterextractor.extractdata(httpmessageconverterextractor.java:110) ~[spring-web-4.3.13.relea.jar:4.3.13.relea]
at org.springframework.cloud.netflix.feign.support.springdecoder.decode(springdecoder.java:59) ~[spring-cloud-netflix-core-1.3.6.relea.jar:1.3.6.relea]
at org.springframework.cloud.netflix.feign.support.responentitydecoder.decode(responentitydecoder.java:47) ~[spring-cloud-netflix-core-1.3.6.relea.jar:1.3.6.relea]
at feign.synchronousmethodhandler.decode(synchronousmethodhandler.java:165) ~[feign-core-9.5.0.jar:?]
at feign.synchronousmethodhandler.executeanddecode(synchronousmethodhandler.java:133) ~[feign-core-9.5.0.jar:?]
at feign.synchronousmethodhandler.invoke(synchronousmethod负荆请罪的历史人物是谁handler.java:76) ~[feign-core-9.5.0.jar:?]
at feign.reflectivefeign$feigninvocationhandler.invoke(reflectivefeign.java:103) ~[feign-core-9.5.0.jar:?]org.springframework.web.client.restclientexception: could not extract respon: no suitable httpmessageconverter found for respon type [channel.domain.channelrespon<tabledata>] and content type [text/json;chart=utf-8]
可以看到返回的类型为[channelfeign#formrecog] content-type: text/json;chart=utf-8
接口返回为json格式数据但却将数据表示为了[text/json]导致feign没有采用json解析器来解析,从而无法将响应数据转化为对应的pojo对象;
源码分析
feign客户端发送请求入口函数invoke()
@override public object invoke(object proxy, method method, object[] args) throws throwable { if ("equals".equals(method.getname())) { try { object otherhandler = args.length > 0 && args[0] != null ? proxy.getinvocationhandler(args[0]) : null; return equals(otherhandler); } catch (illegalargumentexception e) { return fal; } } el if ("hashcode".equals(method.getname())) { return hashcode(); } el if ("tostring".equals(method.getname())) { return tostring(); } // 分发请求 return dispatch.get(method).invoke(args); }
decode()返回请求的解码函数
object decode(respon respon) throws throwable { try { return decoder.decode(respon, metadata.re密松电站turntype()); } catch (feignexception e) { throw e; } catch (runtimeexception e) { throw new decodeexception(e.getmessage(), e); } }
进入decode.decode(),提取数据
@override @suppresswarnings({"unchecked", "rawtypes", "resource"}) public t extractdata(clienthttprespon respon) throws ioexception { messagebodyclienthttpresponwrapper responwrap师说特殊句式per = new messagebodyclienthttpresponwrapper(respon); if (!responwrapper.hasmessagebody() || responwrapper.hamptymessagebody()) { return null; } mediatype contenttype = getcontenttype(responwrapper); for (httpmessageconverter<?> messageconverter : this.messageconverters) { if (messageconverter instanceof generichttpmessageconverter) { generichttpmessageconverter<?> genericmessageconverter = (generichttpmessageconverter<?>) messageconverter; if (genericmessageconverter.canread(this.respontype, null, contenttype)) { if (logger.isdebugenabled()) { logger.debug("reading [" + this.respontype + "] as \"" + contenttype + "\" using [" + messageconverter + "]"); } return (t) genericmessageconverter.read(this.respontype, null, responwrapper); } } if (this.responclass != nu中国新歌声 冠军ll) { if (messageconverter.canread(this.responclass, contenttype)) { if (logger.isdebugenabled()) { logger.debug("reading [" + this.responclass.getname() + "] as \"" + contenttype + "\" using [" + messageconverter + "]"); } return (t) messageconverter.read((class) this.responclass, responwrapper); } } } throw new restclientexception("could not extract respon: no suitable httpmessageconverter found " + "for respon type [" + this.respontype + "] and content type [" + contenttype + "]"); }
进入genericmessageconverter.canread(this.respontype, null, contenttype)
protected boolean canread(mediatype mediatype) { if (mediatype == null) { return true; } for (mediatype supportedmediatype : getsupportedmediatypes()) { if (supportedmediatype.includes(mediatype)) { return true; } } return fal; }
通过断点发现mediatype为接口返回的content-type:text/json类型。而supportedmediatype为application/json,所以返回fal,找不到合适的转换器。
替代feign的解码器,使json解析器同时解析[text/plain]的数据
// 创建一个新的转换器 解析微信的 [text/plain]public class wxmessageconverter extends mappingjackson2httpmessageconverter { public wxmessageconverter(){ list<mediatype> mediatypes = new arraylist<>(); mediatypes.add(mediatype.text_plain); tsupportedmediatypes(mediatypes); }}
注入新的decoder feign将自动 替换
// 解决微信返回参数为[text/plain] 无法转化为json@beanpublic decoder feigndecoder(){ wxmessageconverter wxconverter = new wxmessageconverter(); objectfactory<httpmessageconverters> objectfactory = () -> new httpmessageconverters(wxconverter); return new springdecoder(objectfactory);}
对返回的json字符串使用fastjosn转换
string result = channelfeign.formrecogtest(channelrequest); channelrespon<tabledata> hello = jsonobject.parobject(result, new typereference<channelrespon<tabledata>>() { });
发送请求时对象转换json会自动将属性的首字母小写
解决方法:
//@datapublic class channelrequest { //@jsonfield(name="header") @jsonproperty private channelreqhead header; //@jsonfield(name="body") @jsonproperty private channelreqbody body; // 如果get方法上不加jsonignore,jason化时小写header也会出现 @jsonignore public channelreqhead getheader() { return header; } @jsonignore public void theader(channelreqhead header) { header = header; } @jsonignore public channelreqbody getbody() { return body; } @jsonignore public void tbody(channelreqbody body) { body = body; } }
使用jsonfield不起作用,
不使用jsonignore会生成大写和小写
如:{“header”:xxx,”header”:xxx}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。
本文发布于:2023-04-06 04:09:36,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/0480e69e94cf6e60199918d47247d0c3.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:使用feign发送http请求解析报错的问题.doc
本文 PDF 下载地址:使用feign发送http请求解析报错的问题.pdf
留言与评论(共有 0 条评论) |