Dubbo Hessian2序列化问题
来源:互联网 发布:加盟淘宝孕婴店 编辑:程序博客网 时间:2024/06/07 06:27
问题
定义了一个接口,返回值为Map<String, Byte>
,consumer收到结果后,使用Byte value = map.get(key)
获取结果,抛出了如下类型转换异常:
如下:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Byte at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498)
当时很奇怪,为什么返回值已经是Map<String, Byte>
了,还会抛类型转换异常呢。
分析
首先想到的是通过debug确认返回的类型是否是Byte,设置断点后发现返回的Map的value的类型并不是Byte
而是Integer
,那么为什么会是Integer
呢?
这里猜测这里很可能是dubbo序列化导致的,dubbo默认使用Hessaian2作为序列化协议,所以去看了下Hessian2的序列化实现,果不其然,byte会被反序列化成Integer
代码在Hessian2Input
的readObject
方法:
/** * Reads an arbitrary object from the input stream when the type * is unknown. */ public Object readObject() throws IOException { int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read(); switch (tag) { case 'N': return null; case 'T': return Boolean.valueOf(true); case 'F': return Boolean.valueOf(false); // direct integer case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: return Integer.valueOf(tag - BC_INT_ZERO); /* byte int */ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: return Integer.valueOf(((tag - BC_INT_BYTE_ZERO) << 8) + read()); //byte转换成了Integer //省略其他代码
为了更好说明Hessian2序列化和反序列的问题,可以使用其序列化和反序列化
测试代码如下:
import com.alibaba.com.caucho.hessian.io.Hessian2Input;import com.alibaba.com.caucho.hessian.io.Hessian2Output;import com.google.common.collect.Maps;import org.junit.Test;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.Map;public class Hessian2SerialzeTest { @Test public void test() throws IOException { Map<String, Byte> map = Maps.newHashMap(); map.put("weather", (byte) 1); byte[] bytes = serialize(map); Map<String, Byte> object = (Map<String, Byte>) deserialize(bytes); //这里会抛异常 Byte weather = object.get("weather"); System.out.println(weather); } public static byte[] serialize(Object obj) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); Hessian2Output ho = new Hessian2Output(os); byte[] cc = null; try { if(obj==null) throw new NullPointerException(); ho.writeObject(obj); ho.flushBuffer(); cc=os.toByteArray(); } catch (Exception e) { e.printStackTrace(); }finally{ ho.close(); } return cc; } public static Object deserialize(byte[] by) throws IOException{ try { if(by==null) throw new NullPointerException(); ByteArrayInputStream is = new ByteArrayInputStream(by); Hessian2Input hi = new Hessian2Input(is); return hi.readObject(); } catch (Exception e) { e.printStackTrace(); } return null; }}
运行该test,再一次抛出了Integer转Byte失败的异常,这就证明了我们的猜测,Hessian2序列化确实存在这个问题。
那么问题清晰了,解决就很自然了,要么换一种序列化协议,要么用Object接受Byte,然后把object强转成Byte(证实可行)。
阅读全文
0 0
- Dubbo Hessian2序列化问题
- Hessian2.0序列化协议翻译
- (七)数据序列化-hessian2
- dubbo序列化异常
- Dubbo序列化
- dubbo 序列化实例
- Dubbo Hessian序列化问题 参数为null
- 开发过程中dubbo 实体序列化问题
- dubbo序列化的一点注意
- RPC(Dubbo)的序列化
- java dubbo 图片序列化传输
- dubbo序列化,hibernate.LazyInitializationException could not initialize proxy
- java原生序列化和Kryo(dubbo)序列化性能比较
- 序列化问题
- 序列化NotSerializableException问题
- java 序列化 问题
- 序列化问题!Datatable
- java序列化问题
- Java中Random()函数
- 应用程序池提示:未指定错误,访问站点提示:Service Unavailable
- HBase盲点扫描:集群搭建及hbaseshell使用
- RecyclerView item内部点击事件、item点击事件冲突
- JavaFX控件——TableView
- Dubbo Hessian2序列化问题
- Android Application 多继承
- Oracle导出导入
- 购买二手房为了少纳税签下了“阴阳合同”,明年将坐牢!
- EasyDMA和PPI学习
- 本地仓库关联到远程仓库中
- Java实现内存可见性的两种方法比较:synchronized 和 Volatile以及涉及到锁的剖析
- 微信小程序项目实例
- 关于JMenuBAr,JMenu,JMenuItem,JList,JComboBox