Feign请求响应结果被截取com.fasterxml.jackson.core.io.JsonEOFException

在生产环境使用feign调用外部接口时,偶尔会出现下面错误

2020-10-15 11:00:18,535 [] ERROR com.shein.abc.rmp.controller.RecExplainConfigController - rec_explain_query.fail
f
feign.codec.DecodeException: Error while extracting response for type [class com.alibaba.fastjson.JSONObject] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected end-of-input in field name; nested exception is com.fasterxml.jackson.core.io.JsonEOFException: Unexpected end-of-input in field name
 
 at [Source: (PushbackInputStream); line: 1, column: 108927]
 
        at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:169)
 
        at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:133) 
        
Caused by: org.springframework.web.client.RestClientException: Error while extracting response for type [class com.alibaba.fastjson.JSONObject] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected end-of-input in field name; nested exception is com.fasterxml.jackson.core.io.JsonEOFException: Unexpected end-of-input in field name
 
 at [Source: (PushbackInputStream); line: 1, column: 108927]
 
        at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:115)
 
        at org.springframework.cloud.openfeign.support.SpringDecoder.decode(SpringDecoder.java:60)
 
        at org.springframework.cloud.openfeign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:45)
 
        at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:165)
 
        ... 112 common frames omitted
C
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected end-of-input in field name; nested exception is com.fasterxml.jackson.core.io.JsonEOFException: Unexpected end-of-input in field name
 
 at [Source: (PushbackInputStream); line: 1, column: 108927]
 
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:243)
 
        at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:225)
 
        at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:100)
 
        ... 115 common frames omitted
C
Caused by: com.fasterxml.jackson.core.io.JsonEOFException: Unexpected end-of-input in field name
 
 at [Source: (PushbackInputStream); line: 1, column: 108927]
 
        at 
 
        ... 117 common frames omitted

这个很明显是json反序列化失败,根据提示json字符串不全,根据上面的报错,分别预估了几个可能原因,并针对性的排查。
1、feign中是否有拦截器,截取了响应结果
排查结果:无

2、是否服务端响应的结果就不全
经过排查,服务端响应结果没问题,并支持gzip压缩

3、打印feign的debug日志,并查询出header中的content-length是否与响应结果不一致,这里不了解content-length的可以参考下面链接:
Content-Length是如何工作的
HTTP 协议中的 Transfer-Encoding
这两篇文章中有详细的描述,当实际响应结果比content-length大时会被截取

既然服务端支持gzip压缩,且请求结果返回值比较大,这时我们是否考虑feign开启gzip压缩

feign:
  compression:
    request:
      # 开启请求压缩
      enabled: true
      # 配置压缩的 MIME TYPE
      mime-types: text/xml,application/xml,application/json
      # 配置压缩数据大小的下限
      min-request-size: 2048
    response:
      # 开启响应压缩
      enabled: true

开启压缩后重新请求,报下面的错误

feign.codec.DecodeException: Error while extracting response for type [class com.alibaba.fastjson.JSONObject] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens
 at [Source: (PushbackInputStream); line: 1, column: 2]
	at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:169)
	at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:133)
	at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
	at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
	at com.sun.proxy.$Proxy150.facade(Unknown Source)
	org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.web.client.RestClientException: Error while extracting response for type [class com.alibaba.fastjson.JSONObject] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens
 at [Source: (PushbackInputStream); line: 1, column: 2]
	at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:115)
	at org.springframework.cloud.openfeign.support.SpringDecoder.decode(SpringDecoder.java:60)
	at org.springframework.cloud.openfeign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:45)
	at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:165)
	... 114 common frames omitted
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens
 at [Source: (PushbackInputStream); line: 1, column: 2]
	at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:243)
	at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:225)
	at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:100)
	... 117 common frames omitted
Caused by: com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens
 at [Source: (PushbackInputStream); line: 1, column: 2]
	at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1804)
	at 
	... 119 common frames omitted

这个报错比较明显了,反序列化解析出问题,经过排查发现是HttpURLConnection不支持gzip反序列化,SpringCloud需要升级到Hoxton才能解决该问题:https://github.com/spring-cloud/spring-cloud-openfeign/pull/230
还有一种方案是将httpclient换成okhttp,如下配置变更:

feign:
  okhttp:
    enabled: true
  httpclient:
    enabled: false

pom中增加相关依赖

        
        
            io.github.openfeign
            feign-okhttp
        

配置后重新启动,不再报错。

参考链接:
https://www.jianshu.com/p/df37eb5f2169
https://blog.csdn.net/wo18237095579/article/details/83344529
https://imququ.com/post/transfer-encoding-header-in-http.html
https://blog.piaoruiqing.com/2019/09/08/do-you-know-content-length/

你可能感兴趣的:(springcloud技术分享,feign,响应截取,反序列化失败)