通过Fegin远程调用 ,返回JPA Page 对象报错
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of org.springframework.data.domain.Page: abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: java.io.PushbackInputStream@5ebf9e24; line: 2, column: 12] (through reference chain: com.sysware.cloud.plugin.bean.Response["data"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1012) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:216) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:504) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:357) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3814) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2938) ~[jackson-databind-2.8.10.jar:2.8.10]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:223) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:96) ~[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.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:45) ~[spring-cloud-netflix-core-1.4.2.RELEASE.jar:1.4.2.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.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:108) ~[feign-hystrix-9.5.0.jar:?]
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302) ~[hystrix-core-1.5.12.jar:1.5.12]
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298) ~[hystrix-core-1.5.12.jar:1.5.12]
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46) ~[rxjava-1.2.0.jar:1.2.0]
... 26 more
大概意思是:不能构造实例org.springframework.data.domain.Page :抽象类型要么需要映射到具体类型,要么有自定义反序列化器,要么用额外的类型信息进行实例化 。
解释下啊,第一种办法就是page是一个接口,反序列化需要配置映射到具体的类型在Page类上面加@JsonDeserialize注解,指定反序列化的具体实现,但是Page类并不是我们自定义的类,所以在Page接口上加注解应该是不现实的
第二种办法就是,需要自定义反序列化器,大概就是说序列化和反序列化是使用默认的readOjbect ,和 writeObject ,但是通过默认的readOject解析不了,需要用户自定义解析Page的解析。
第三方式就是,自定义抽象类型的实现类,用实现类接受。
我们查找到Page的实现类,框架本身已经提供PageImpl,所以我们换成PageImpl接受返回值。
然而,换成PageImpl接受报如下错误:
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of org.springframework.data.domain.PageImpl: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: java.io.PushbackInputStream@6e88a853; line: 3, column: 5] (through reference chain: com.sysware.cloud.plugin.bean.Response["data"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1012) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1206) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:314) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:504) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:357) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3814) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2938) ~[jackson-databind-2.8.10.jar:2.8.10]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:223) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:96) ~[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.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:45) ~[spring-cloud-netflix-core-1.4.2.RELEASE.jar:1.4.2.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.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:108) ~[feign-hystrix-9.5.0.jar:?]
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302) ~[hystrix-core-1.5.12.jar:1.5.12]
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298) ~[hystrix-core-1.5.12.jar:1.5.12]
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46) ~[rxjava-1.2.0.jar:1.2.0]
... 26 more
大概意思是说:不能构造实例 org.springframework.data.domain.PageImpl : 没有合适的构造函数(此处还在查资料jackson反序列化和构造函数的关系),然后查阅PageImpl的源码,发现确实没有无参的构造函数
public PageImpl(List<T> content, Pageable pageable, long total) {
super(content, pageable);
this.pageable = pageable;
this.total = !content.isEmpty() && pageable != null && (long)(pageable.getOffset() + pageable.getPageSize()) > total?(long)(pageable.getOffset() + content.size()):total;
}
public PageImpl(List<T> content) {
this(content, (Pageable)null, null == content?0L:(long)content.size());
}
然后我们通过自定义类继承PageImpl ,并添加无参构造函数,代码如下(这是最终版,其实刚开始的时候Sort上没有加@JsonDeserialize(using=CustomSortDeserializer.class)),后面说加这个注解的作用。
package com.sysware.cloud.plugin.commons.http; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Data;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import java.util.ArrayList;
import java.util.List; /**
* Created by tianwenqing on 2018/7/9.
*/
@Data
public class RestResponsePage<T> extends PageImpl<T> {
public RestResponsePage(List<T> content, Pageable pageable, long total) {
super(content, pageable, total);
} private int number;
private int size;
private int totalPages;
private int numberOfElements;
private long totalElements;
private boolean previousPage;
private boolean first;
private boolean nextPage;
private boolean last;
private List<T> content;
@JsonDeserialize(using=CustomSortDeserializer.class)
private Sort sort; public RestResponsePage(List<T> content) {
super(content);
} public RestResponsePage() {
super(new ArrayList<T>());
} public PageImpl<T> pageImpl() {
return new PageImpl<T>(getContent(), new PageRequest(getNumber(),
getSize(), getSort()), getTotalElements());
}
}
package com.sysware.cloud.plugin.commons.http; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.springframework.data.domain.Sort; import java.io.IOException; /**
* Created by tianwenqing on 2018/7/9.
*/
public class CustomSortDeserializer extends JsonDeserializer<Sort> {
@Override
public Sort deserialize(JsonParser jp, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
ArrayNode node = jp.getCodec().readTree(jp);
Sort.Order[] orders = new Sort.Order[node.size()];
int i = 0;
for(JsonNode obj : node){
orders[i] = new Sort.Order(Sort.Direction.valueOf(obj.get("direction").asText()), obj.get("property").asText());
i++;
}
Sort sort = new Sort(orders);
return sort;
}
}
上面的的两个类就是最终代码,然后FeginClient端接受的时候用RestResponsePage替代Page,即可。
下面介绍@JsonDeserialize(using=CustomSortDeserializer.class)
刚开始创建完RestResponsePage类,没有加@JsonDeserialize(using=CustomSortDeserializer.class) 直接引用,结果又报下面的错:
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of org.springframework.data.domain.Sort out of START_ARRAY token
at [Source: java.io.PushbackInputStream@5f88be0f; line: 84, column: 14] (through reference chain: com.sysware.cloud.plugin.bean.Response["data"]->com.sysware.cloud.test.aggregation.RestResponsePage["sort"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1122) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1075) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromArray(BeanDeserializerBase.java:1370) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:174) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:150) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:504) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:357) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:504) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:357) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3814) ~[jackson-databind-2.8.10.jar:2.8.10]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2938) ~[jackson-databind-2.8.10.jar:2.8.10]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:223) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:96) ~[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.4.2.RELEASE.jar:1.4.2.RELEASE]
at org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:45) ~[spring-cloud-netflix-core-1.4.2.RELEASE.jar:1.4.2.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.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:108) ~[feign-hystrix-9.5.0.jar:?]
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302) ~[hystrix-core-1.5.12.jar:1.5.12]
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298) ~[hystrix-core-1.5.12.jar:1.5.12]
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46) ~[rxjava-1.2.0.jar:1.2.0]
... 26 more
大概意思是说不能反序列化Sort属性,所以我们使用自定义反序列化器序列化Sort,至于为什么不能反序列化,google找到如下解释,还没有看太懂
If you look at Sort, you'll see that it implements Iteratable for Order. And if you examine Order defined in the same class, you'll see the fields in my example JSON. So when Sort is serialized, it is serialized as a list of Order, which is why deserializing into Sort needs a custom deserializer implementation, and also why deserializing without a custom implementation fails (because it's trying to deserialize an array into a single object).
During deserialization, when a setter annotated with @JsonDeserializer is encountered as each property is deserialized, Jackson uses the supplied deserializer to deserialize that specific property.
通过Fegin远程调用 ,返回JPA Page 对象报错的更多相关文章
- ajax 调用 .net core WebAPI,报错 400 (Bad Request) Unexpected character encountered while parsing value
此文由博主前两天的提问及 dudu 的回答整理,地址:https://q.cnblogs.com/list/myquestion 情况说明 基于 .net core 写了一个 Web API,用 po ...
- Jpa自定义查询报错(Failed to convert from type [java.lang.Object[]] to type)
Jpa自定义查询报错 问题背景 今天遇到一个奇怪的报错"Failed to convert from type [java.lang.Object[]] to type",这个报错 ...
- java调用本地方法的时候报错 could not find the main class:xx.program will exit
如图所示,当在java调用本地方法的时候报错 我的解决办法是把dll文件放到System.out.println(System.getProperty("java.library.path& ...
- 关于 JavaScript 中一个小细节问题 (在控制台中直接 {Name:'王尼玛',Age:20} 对象报错问题)
在 Chrome 浏览器,大家可能遇到这样一个小问题. 随便输入一个 Object 对象 ,比如 {Name:'王尼玛',Age:20} ,将会报错.之前,也从来没去考虑过到底是为啥原因. 今天,刚 ...
- js Fetch返回数据res.json()报错问题
前言 一直以来在简单的场景中经常使用fetch代替第三方请求库, fetch是JavaScript的原生函数, 简单.高效.快速.稳定.可定制等等诸多优点.一直也是用着很是舒服,直到有一天它竟然报错了 ...
- vc调用BCB的dll 参数传递 报错
可能原因: 调用方式约定不一致. 函数调用约定如下: 1. __cdecl:C 和 C++ 程序的缺省调用规范. 2. __stdcall:标准调用约定(即WINAPI调用约定),也就是pascal调 ...
- List转换成JSON对象报错(二)
List转换成JSON对象 1.具体报错如下 Exception in thread "main" java.lang.NoClassDefFoundError: org/apac ...
- List转换成JSON对象报错(一)
List转换成JSON对象 1.具体报错如下 Exception in thread "main" java.lang.NoClassDefFoundError: org/apac ...
- 微信授权、获取用户openid-纯前端实现——jsonp跨域访问返回json数据会报错的纯前端解决办法
近来,倒霉的后台跟我说让我拿个openid做微信支付使用,寻思很简单,开始干活. 首先引导用户打开如下链接,只需要将appid修改为自己的就可以,redirect_url写你的重定向url https ...
随机推荐
- SSH整合不错的博客
https://blog.csdn.net/struggling_rong/article/details/63153833?locationNum=9&fps=1 好好看看看哦
- Web安全学习笔记之Kali配置国内软件更新源
0x0 前言 Kali安装完成后,默认是国外官方的更新源,更新速度4kb/s太酸爽了... 0x1 把更新源设置为国内阿里云或者中科大的镜像源 命令行:leafpad /etc/apt/sources ...
- LSTM java 实现
由于实验室事情缘故,需要将Python写的神经网络转成Java版本的,但是python中的numpy等啥包也不知道在Java里面对应的是什么工具,所以索性直接寻找一个现成可用的Java神经网络框架,于 ...
- Spring提前加载与懒加载
首先,Spring默认是提前加载,这意味着当项目启动,spring初始化,spring会把所有的扫描包下的 ,所有带spring 注解(@Component.@Repository.@Service. ...
- mongodb入门很简单(2)
mongodb的安装 1.下载mongodb: www.mongodb.org 下载最新的stable版:我下载的版本是3.2.5 2.解压文件 3.不用编译:本身就是编译后的二进制可执行文件 打开 ...
- nginx解决跨域问题
背景:由于公司有个项目是.net写的,但是开发人员已经离职好久了.老项目也不怎么变动就没有招新人,于是乎就把项目交接给了一位php开发人员. 今天那位php开发人员跑过来,说https://wap.a ...
- Spring容器基础ClassPathXmlApplicationContext(一起看源码)
ApplicationContext相比较于BeanFactory,扩展了很多功能.也就是说前者包含了后者的所有功能.使用前者加载XML的方式:ApplicationContext app=new C ...
- com.mysql.jdbc.MysqlDataTruncation:Data Truncation:Data too long for column '字段name' at row 1
1.问题描述: 在mysql插入数据的时候报错:Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long fo ...
- 转:eclipse与myeclipse恢复已删除的文件和代码
- ETL增量处理总结
1 LOG表 1.1 思路 用log表记录业务库某表yw_tableA发生变化数据的主键.数据进入BI库目标表bi_tableA前,先根据log表记录的主键进行delete. 1.2 设计 1.2.1 ...