使用dubbo自定义返回对象异常
来源:互联网 发布:华硕笔记本怎么样 知乎 编辑:程序博客网 时间:2024/06/05 15:43
最近修改了dubbo服务端的返回对象,引用了spring-data-commons中的Page接口,还是使用默认的dubbo协议,也就是netty+hessian2;当消费端连接过来获取数据时,报了下面这个异常
Caused by: com.alibaba.com.caucho.hessian.io.HessianProtocolException: 'org.springframework.data.domain.PageImpl' could not be instantiated at com.alibaba.com.caucho.hessian.io.JavaDeserializer.instantiate(JavaDeserializer.java:275) at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:155) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2067) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1592) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1576) at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectFieldDeserializer.deserialize(JavaDeserializer.java:396) ... 29 more
上网查过后发现hessian反序列化:
参数及返回值需实现Serializable接口
参数及返回值需有无参构造函数(可以是private的)或者有参构造所有函数允许传入null值。
而Page接口的实现类PageImpl继承的抽象父类Chunk并未提供无参构造函数,也可以通过查看源码com.alibaba.com.caucho.hessian.io.JavaDeserializer
/** * Creates a map of the classes fields. */ protected static Object getParamArg(Class cl) { if (! cl.isPrimitive()) return null; else if (boolean.class.equals(cl)) return Boolean.FALSE; else if (byte.class.equals(cl)) return new Byte((byte) 0); else if (short.class.equals(cl)) return new Short((short) 0); else if (char.class.equals(cl)) return new Character((char) 0); else if (int.class.equals(cl)) return Integer.valueOf(0); else if (long.class.equals(cl)) return Long.valueOf(0); else if (float.class.equals(cl)) return Float.valueOf(0); else if (double.class.equals(cl)) return Double.valueOf(0); else throw new UnsupportedOperationException(); }
由于PageImpl的两个构造函数的参数都不是基本类型,因此_constructorArgs所包含的值全部是null。
知道问题所在了,那么我们只需更改传输的序列化方式,下面给出两种解决方案让我们还可以用到spring-data-commons中的Page接口:
1、dubbo的序列化使用除了hessian2的其他序列化方式,测试的序列化框架有kryo、fastJson,发现如果用fastJson作为序列化的话,不报错能正常返回,但是data数据是空的;所以推荐使用kryo,也是一种非常高效的序列化框架,其他的可以自行测试。dubbo自带实现有的序列化方式在包com.alibaba.dubbo.common.serialize.support下,当然你也参考官方文档自行实现序列化扩展,比如protobuf。
序列化扩展示例
服务端dubbo增加配置如下:
<dubbo:protocol name="dubbo" port="20088" serialization="kryo"/>
客户端dubbo增加配置如下:
<dubbo:protocol serialization="kryo"/>
2、改用其他协议,比如rmi,hessian,http
服务端dubbo修改配置如下:
<dubbo:protocol name="rmi" port="1090"/><dubbo:protocol name="hessian" port="8282"/><!-- 下面就可以引用传输协议了 --><dubbo:service interface="xxx.xx.x.TestService" ref="testService" protocol="hessian,rmi"/>
客户端dubbo修改配置如下:
<!-- protocol可选服务端提供的hessian,rmi --><dubbo:reference id="testService" interface="xxx.xx.x.TestService" protocol="hessian"/>
推荐第一种,毕竟默认的dubbo协议还是在数据小但是高并发的情况下有优势的。
- 使用dubbo自定义返回对象异常
- Dubbo抛出自定义异常
- Dubbo抛出自定义异常
- dubbo使用POJO对象传输数据的RemotingException异常问题
- dubbo处理自定义异常问题
- Hibernate高级使用:查询返回自定义对象
- 使用jdbcTemplate查询返回自定义对象集合
- 使用jdbcTemplate查询返回自定义对象集合
- ExpandListView使用自定义对象时异常
- 初学java自定义异常对象的使用
- Dubbo生产者抛出自定义异常的问题
- Dubbo生产者抛出自定义异常的问题
- dubbo捕获提供者抛出的自定义异常
- Dubbo生产者抛出自定义异常的问题
- Hibernate 查询多个字段返回的list如何转为自定义对象,以及转换异常
- 使用Dubbo框架,异常处理原则
- MVC自定义对象返回JSON
- 自定义MyBatis返回Map对象
- 绘图
- Android 音效流程分析
- 一条mysql update if then 语句
- 高性能渲染图层--GraphicLayer
- solr数据导入后的query,其实是这样的
- 使用dubbo自定义返回对象异常
- 场景识别学习笔记日记2016.11.24
- Android反编译的软件是Android Killer
- Visual Studio各种路径宏说明
- Maven多web模块工程构建各种Error listenerStart启动失败情况及最终解决过程记录
- 封装的个人总结
- C++学习【原创】stable_partition函数的应用
- Java Web应用——监听器初识
- C++ 模板类(廿三)--template模板类使用