Bootstrap

记一次Feign调用报错feign.codec.DecodeException: Error while extracting response for type [java.util.List...

背景:

        在今天工作时,临时收到生产问题,检查发现是在本服务Feign远程调用其他服务时方法时发生的,具体报错详情,及原因和解决方法均记录在下方。

报错详情:

        feign.codec.DecodeException: Error while extracting response for type [java.util.List<Object>] and content type [application/json]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.util.ArrayList<Object>` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList<Object>` out of START_OBJECT token
 at [Source: (PushbackInputStream); line: 1, column: 1]

 报错原因及解决方法:

        原因:调用方接收数据的类型和服务端传回的数据类型不一致。

1、经过检查代码,发现两边所用的对象数据类型完全一致,甚至使用的类是公共jar下的同一个类,很奇怪,那为什么会发生这样的转换异常呢?

2、拉取生产代码,在测试库进行测试,发现完全正常,无法复现问题,那究竟是怎么造成的,难道是环境不一致造成的?

3、由于生产环境不能操作调试,测试环境无法复现,问题开始难办了,这时开始在网上搜索是否有同样的问题,发现大多这样异常均是数据类型不一致导致的,开始根据如下问题一一排查

  1. 返回的 JSON 字符串与预期的 Java 类型不匹配。例如,JSON 中的某个字段为字符串类型,但在 Java 类型中却定义为数字类型。

  2. 返回的 JSON 字符串属性名与 Java 类型中定义的属性名不匹配。在这种情况下,Feign 无法将 JSON 字符串正确地转换为 Java 对象。

  3. Feign 默认使用 Jackson 库进行 JSON 反序列化,如果返回的 JSON 字符串格式不符合标准,就会出现反序列化错误。例如,JSON 字符串中包含注释、单引号或未使用双引号引起来的字符串等。

  4. 可能是服务消费方(A服务)和服务提供方(B服务)使用的 JSON 库版本不一致,导致反序列化失败。可以尝试使用相同版本的 JSON 库,或者在 Feign 客户端中指定使用某个特定版本的 JSON 库。

4、在检查了上述问题后均没解决,这时突然灵感乍现,JSON parse error: Cannot deserialize instance of `java.util.ArrayList<Object>` out of START_OBJECT token,这段异常提示,不能由对象转换为List,是否数据问题或者代码逻辑使被调用方返回的异常格式的对象,这时联系有生产环境查询权限的同事进行确认,发现确实存在数据问题导致被调用服务内抛出了异常,返回了异常对象最终出现JSON parse error。

到此问题已解决,处理了被调用方问题后(无法更改被调用方时,本服务应该try-catch,将可能出现的异常自定义处理),一切正常。

;