Dubbo使用Hessian2序列化时针对Byte类型出现java.lang.ClassCastException
背景
前不久翎野君帮同事看一个问题,比较有启发性,特记录一下。一个dubbo rpc方法中,从请求对象中取出Set<Byte>变量进行循环操作,然后出现下面的问题。
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Byte
乍一看还有些费解,好好的代码,看上去那么的乖巧可爱,怎么会突然冒出来这个问题,带着怀疑的态度自己本地编写了Test方法试验了一下,发现也没有问题。然后就把目光放在dubbo传输框架上面了,查阅了一些资料,发现dubbo默认的hessian2序列化协议不支持Byte类型。
问题复现
package com.lingyejun.test; import com.alibaba.com.caucho.hessian.io.Hessian2Input; import com.alibaba.com.caucho.hessian.io.Hessian2Output; import org.junit.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class HessianTest { @Test public void test() throws IOException { Byte basicByte = 88; byte[] basicByteArray = serialize(basicByte); // 序列化后得到的是Integer类型的变量 Object obj = deserialize(basicByteArray); // 会报类型转换错误 Byte desB = (Byte) obj; Set<Byte> byteSet = new HashSet<>(); byteSet.add((byte) 11); byteSet.add((byte) 6); byte[] byteSetArray = serialize(byteSet); Set<Byte> dsByteSet = (Set<Byte>) deserialize(byteSetArray); // 会报类型转换错误 for (Byte aByte : dsByteSet) { System.out.println(aByte); } Map<Byte, Byte> byteMap = new HashMap<>(); byteMap.put((byte) 2, (byte) 3); byte[] byteMapArray = serialize(byteMap); Map<Byte, Byte> dsByteMap = (Map<Byte, Byte>) deserialize(byteMapArray); // 会报类型转换错误 Byte value = dsByteMap.get(2); System.out.println(value); } 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) { 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; } }
过程
hessian2官方文档:http://hessian.caucho.com/doc/hessian-serialization.html
Hessian 的对象序列化机制有 8 种原始类型:
- 原始二进制数据
- boolean
- 64-bit date(64 位毫秒值的日期)
- 64-bit double
- 32-bit int
- 64-bit long
- null
- UTF-8 编码的 string
我们发现基础类型中并不支持Byte类型,让我们在通过源码验证一下。
在序列化时将Byte、Shor、Integer统一按照int类型进行写流。
在反序列化的过程中将byte int 按照Integer类型进行读取
警示
在使用Hessian协议对Byte类型进行序列化操作时会发生类型转化的问题,故而Byte及相关集合类如Set<Byte>、List<Byte>、Map<Byte, Byte>等尽量避免使用。
本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。
作者:翎野君
出处:http://www.cnblogs.com/lingyejun/
若本文如对您有帮助,不妨点击一下右下角的【推荐】。
如果您喜欢或希望看到更多我的文章,可扫描二维码关注我的微信公众号《翎野君》。
转载文章请务必保留出处和署名,否则保留追究法律责任的权利。
出处:http://www.cnblogs.com/lingyejun/
若本文如对您有帮助,不妨点击一下右下角的【推荐】。
如果您喜欢或希望看到更多我的文章,可扫描二维码关注我的微信公众号《翎野君》。
转载文章请务必保留出处和署名,否则保留追究法律责任的权利。