当前位置:   article > 正文

Feign源码问题导致请求参数丢失_feign.codec.decodeexception: error while extractin

feign.codec.decodeexception: error while extracting response for type

一、错误日志

feign.codec.DecodeException: Error while extracting response for type [***] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `***` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `***` out of START_ARRAY token at [Source: (PushbackInputStream); line: 1, column: 1]

 

二、错误原因排查

1、服务端开启了gzip,而客户端未开启;

2、参数未进行json序列化;

3、jackson反序列化失败引起:实体bean对应不正确,或者时间格式化错误;

发现这个错误的时候,也是度娘一顿搜索,逐个排查,但是都一一排除了;因为这个错误不是说一致存在,而是偶尔引起的,这就很烦人,因为我用postman测试服务端接口,怎么测试都是好使的。

并且服务也都开启了gzip,客户端使用的是httpclient,服务端是okhttp;后来搜到可能是因为httpclient源码问题导致解析gzip失败,所以给客户端换为okhttp(默认支持),但是还是会出现同样错误。

PS:现在才想起来不是所有都有这个问题,只是偶尔该接口才会报这个;所以我找到生产数据进行postman测试,发现仍然ok;然后彻底方了!然后我就查看controller中所有接口,虽然都遵循了restful接口规范,但是该接口(获取单个实体Bean,Get)与获取所有实体Bean(List,Get)请求路径一样,只是本接口中使用了@GetMapping的params来指定必传参数项!

脑子一抖,会不会是请求到了List的接口上,导致了客户端解析返回值错误!poastman测试,少勾选一个参数,然后我就重现了该错误。。。

从数据库中取到的真实数据,确实有一个字段的值是空的,但是怎么从客户端到服务端就给我少了一个参数,难道是Feign导致的!

随后,度娘加打断点发现Feign真的会把null值给过滤掉!

这是Feign源码:

  1. @Override
  2. public RequestTemplate create(Object[] argv) {
  3. RequestTemplate mutable = RequestTemplate.from(metadata.template());
  4. if (metadata.urlIndex() != null) {
  5. int urlIndex = metadata.urlIndex();
  6. checkArgument(argv[urlIndex] != null, "URI parameter %s was null", urlIndex);
  7. mutable.target(String.valueOf(argv[urlIndex]));
  8. }
  9. Map<String, Object> varBuilder = new LinkedHashMap<String, Object>();
  10. for (Entry<Integer, Collection<String>> entry : metadata.indexToName().entrySet()) {
  11. int i = entry.getKey();
  12. Object value = argv[entry.getKey()];
  13. if (value != null) { // Null values are skipped.
  14. if (indexToExpander.containsKey(i)) {
  15. value = expandElements(indexToExpander.get(i), value);
  16. }
  17. for (String name : entry.getValue()) {
  18. varBuilder.put(name, value);
  19. }
  20. }
  21. }
  22. RequestTemplate template = resolve(argv, mutable, varBuilder);
  23. if (metadata.queryMapIndex() != null) {
  24. // add query map parameters after initial resolve so that they take
  25. // precedence over any predefined values
  26. Object value = argv[metadata.queryMapIndex()];
  27. Map<String, Object> queryMap = toQueryMap(value);
  28. template = addQueryMapQueryParameters(queryMap, template);
  29. }
  30. if (metadata.headerMapIndex() != null) {
  31. template =
  32. addHeaderMapHeaders((Map<String, Object>) argv[metadata.headerMapIndex()], template);
  33. }
  34. return template;
  35. }

可以看到注释会把null值跳过!

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/813891
推荐阅读
相关标签
  

闽ICP备14008679号