赞
踩
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源码:
- @Override
- public RequestTemplate create(Object[] argv) {
- RequestTemplate mutable = RequestTemplate.from(metadata.template());
- if (metadata.urlIndex() != null) {
- int urlIndex = metadata.urlIndex();
- checkArgument(argv[urlIndex] != null, "URI parameter %s was null", urlIndex);
- mutable.target(String.valueOf(argv[urlIndex]));
- }
- Map<String, Object> varBuilder = new LinkedHashMap<String, Object>();
- for (Entry<Integer, Collection<String>> entry : metadata.indexToName().entrySet()) {
- int i = entry.getKey();
- Object value = argv[entry.getKey()];
- if (value != null) { // Null values are skipped.
- if (indexToExpander.containsKey(i)) {
- value = expandElements(indexToExpander.get(i), value);
- }
- for (String name : entry.getValue()) {
- varBuilder.put(name, value);
- }
- }
- }
-
- RequestTemplate template = resolve(argv, mutable, varBuilder);
- if (metadata.queryMapIndex() != null) {
- // add query map parameters after initial resolve so that they take
- // precedence over any predefined values
- Object value = argv[metadata.queryMapIndex()];
- Map<String, Object> queryMap = toQueryMap(value);
- template = addQueryMapQueryParameters(queryMap, template);
- }
-
- if (metadata.headerMapIndex() != null) {
- template =
- addHeaderMapHeaders((Map<String, Object>) argv[metadata.headerMapIndex()], template);
- }
-
- return template;
- }
可以看到注释会把null值跳过!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。