使用feign发送http请求解析报错
错误如下:
发送请求开始
-----
[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;charset=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.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.codec.DecodeException: Could not extract response: no suitable HttpMessageConverter found for response type [channel.domain.ChannelResponse<TableData>] and content type [text/json;charset=UTF-8]] with root cause
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [channel.domain.ChannelResponse<TableData>] and content type [text/json;charset=UTF-8]at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:110) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]at org.springframework.cloud.netflix.feign.support.SpringDecoder.decode(SpringDecoder.java:59) ~[spring-cloud-netflix-core-1.3.6.RELEASE.jar:1.3.6.RELEASE]at org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:47) ~[spring-cloud-netflix-core-1.3.6.RELEASE.jar:1.3.6.RELEASE]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(SynchronousMethodHandler.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 response: no suitable HttpMessageConverter found for response type [channel.domain.ChannelResponse<TableData>] and content type [text/json;charset=UTF-8]
可以看到返回的类型为[ChannelFeign#formRecog] content-type: text/json;charset=UTF-8
错误原因
接口返回为JSON格式数据但却将数据表示为了[text/json]导致Feign没有采用JSON解析器来解析,从而无法将响应数据转化为对应的POJO对象;
源码分析
feign客户端发送请求入口函数invoke()
@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if ("equals".equals(method.getName())) {try {ObjectotherHandler =args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;return equals(otherHandler);} catch (IllegalArgumentException e) {return false;}} else if ("hashCode".equals(method.getName())) {return hashCode();} else if ("toString".equals(method.getName())) {return toString();}// 分发请求return dispatch.get(method).invoke(args);}
decode()返回请求的解码函数
Object decode(Response response) throws Throwable {try {return decoder.decode(response, metadata.returnType());} catch (FeignException e) {throw e;} catch (RuntimeException e) {throw new DecodeException(e.getMessage(), e);}}
进入decode.decode(),提取数据
@Override@SuppressWarnings({"unchecked", "rawtypes", "resource"})public T extractData(ClientHttpResponse response) throws IOException {MessageBodyClientHttpResponseWrapper responseWrapper = new MessageBodyClientHttpResponseWrapper(response);if (!responseWrapper.hasMessageBody() || responseWrapper.hasEmptyMessageBody()) {return null;}MediaType contentType = getContentType(responseWrapper);for (HttpMessageConverter<?> messageConverter : this.messageConverters) {if (messageConverter instanceof GenericHttpMessageConverter) {GenericHttpMessageConverter<?> genericMessageConverter =(GenericHttpMessageConverter<?>) messageConverter;if (genericMessageConverter.canRead(this.responseType, null, contentType)) {if (logger.isDebugEnabled()) {logger.debug("Reading [" + this.responseType + "] as \"" +contentType + "\" using [" + messageConverter + "]");}return (T) genericMessageConverter.read(this.responseType, null, responseWrapper);}}if (this.responseClass != null) {if (messageConverter.canRead(this.responseClass, contentType)) {if (logger.isDebugEnabled()) {logger.debug("Reading [" + this.responseClass.getName() + "] as \"" +contentType + "\" using [" + messageConverter + "]");}return (T) messageConverter.read((Class) this.responseClass, responseWrapper);}}}throw new RestClientException("Could not extract response: no suitable HttpMessageConverter found " +"for response type [" + this.responseType + "] and content type [" + contentType + "]");}
进入genericMessageConverter.canRead(this.responseType, null, contentType)
protected boolean canRead(MediaType mediaType) {if (mediaType == null) {return true;}for (MediaType supportedMediaType : getSupportedMediaTypes()) {if (supportedMediaType.includes(mediaType)) {return true;}}return false;}
通过断点发现mediaType为接口返回的content-type:text/json类型。而supportedMediaType为application/json,所以返回false,找不到合适的转换器。
解决方案一
替代Feign的解码器,使json解析器同时解析[text/plain]的数据
// 创建一个新的转换器 解析微信的 [text/plain]
public class WxMessageConverter extends MappingJackson2HttpMessageConverter {public WxMessageConverter(){List<MediaType> mediaTypes = new ArrayList<>();mediaTypes.add(MediaType.TEXT_PLAIN);setSupportedMediaTypes(mediaTypes);}
}
注入新的Decoder Feign将自动 替换
// 解决微信返回参数为[text/plain] 无法转化为json
@Bean
public Decoder feignDecoder(){WxMessageConverter wxConverter = new WxMessageConverter();ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(wxConverter);return new SpringDecoder(objectFactory);
}
参考:Buynow_Zhao博客 https://blog.csdn.net/a610786189/article/details/80508353?utm_source=copy
解决方案二
对返回的json字符串使用fastjosn转换
String result = channelFeign.formRecogTest(channelRequest);ChannelResponse<TableData> hello = JSONObject.parseObject(result,new TypeReference<ChannelResponse<TableData>>() {});
错误2
发送请求时对象转换json会自动将属性的首字母小写
解决方法:
//@Data
public class ChannelRequest {//@JSONField(name="Header")@JsonPropertyprivate ChannelReqHead Header;//@JSONField(name="Body")@JsonPropertyprivate ChannelReqBody Body;// 如果get方法上不加JsonIgnore,jason化时小写header也会出现@JsonIgnorepublic ChannelReqHead getHeader() {return Header;}@JsonIgnorepublic void setHeader(ChannelReqHead header) {Header = header;}@JsonIgnorepublic ChannelReqBody getBody() {return Body;}@JsonIgnorepublic void setBody(ChannelReqBody body) {Body = body;}}
使用jsonField不起作用,
不使用jsonIgnore会生成大写和小写
如:{“Header”:xxx,"header":xxx}
使用feign发送http请求解析报错相关推荐
- ajax 前端报错,Django ajax 发送post请求 前端报错解决
首先在from表单中加上 {% csrf_token %} 如果还出现 POST http://127.0.0.1:8000/login/ 403 (Forbidden) send @ jquery. ...
- python邮件发送csv附件_Python2.7 smtplib发送带附件邮件报错STARTTLS解决方法
最近在SIOMP系统中添加一项功能时,即自动发送带附件邮件到指定邮箱时,发现在发送时报错:错误信息:STARTTLS extension not supported by server.很是奇怪,但发 ...
- Unity3D使用LitJson.dll解析报错问题
报错内容: JsonException: Invalid character ' LitJson.Lexer.NextToken () (at <e591cc6acad24a94a39b4890 ...
- 解析报错 No such provider: BC
解析报错 No such provider: BC 我在网上找了,有几种方法.修改配置文件和添加代码(代码我也不太明白,希望懂的老铁可以解释一下) 修改配置文件我也试过,是可行的,不过不推荐 找到 ...
- springboot post 请求参数过长请求接口报错 An HTTP line is larger than 4096 bytes
springboot项目post请求参数过长请求接口报错如下: 解决办法将post请求参数值调大: server:tomcat:max-http-form-post-size: 5MB
- 【SpringCloud】请求响应报错cannot be cast to org.springframework.core.io.buffer.NettyDataBufferFactory
springcloud gateway请求响应报错 org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast ...
- 谷歌正常,IE浏览器get请求方式 报错400 解决办法
兼容IE浏览器请求: 现象 项目迁移中,页面迁移完成后,谷歌浏览器本地环境,测试环境访问正常,IE浏览器本地访问正常,测试访问报400 分析 请求报400,初步认定参数问题引起: 本地无法重现,找到测 ...
- 解决json解析报错:Expecting value: line 1 column 1 (char 0)
一般来说,出现这种Expecting value: line 1 column 1 (char 0)报错,一般原因都是返回的数据的格式不是json格式的. 今天在用flask写一个接口,测试接口的时候 ...
- json解析报错:HttpMessageNotReadableException: JSON parse error: Unexpected character (‘/‘ (code 47))
报错信息 at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 109] ...
最新文章
- Linux下正确使用getifaddrs()函数避免内存泄露
- 选购高清监控摄像机的十个技巧
- Facebook开源算法代码库,轻松复现前沿视频理解模型
- 常见拒绝服务型攻击原理及行为特征
- LeetCode题解之Copy List with Random Pointer
- iCOM组件(iComponent,应用或学习组件)
- 问题 D: 寻求勾股数
- 【JAVA笔记】线程(1):多线程的介绍和实现
- IntelliJ IDEA 2018.2设置背景图片及透明度
- 解决在ubuntu 12.10安装vmware-tools实现文件共享问题
- 例2.1 排序 - 九度教程第1题(排序)
- 夺命雷公狗----Git---2---基本用法
- cpri带宽不足的解决方法_CPRI基带数据的低损耗压缩
- 网站域名备案需要怎么做?
- Tkinter 学习笔记
- Java反射专题笔记
- wamp下localhost目录Your Projects下项目无法打开解决方案
- 凯撒密码加解密及破解实现原理
- 《三国演义》之人物出场统计
- 超全Redis命令总结(备忘)(建议赶紧收藏)