zoukankan      html  css  js  c++  java
  • 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>等尽量避免使用。

    本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。

    原文链接:https://www.cnblogs.com/lingyejun/p/15586083.html

    作者:翎野君
    出处:http://www.cnblogs.com/lingyejun/
    若本文如对您有帮助,不妨点击一下右下角的【推荐】。
    如果您喜欢或希望看到更多我的文章,可扫描二维码关注我的微信公众号《翎野君》。
    转载文章请务必保留出处和署名,否则保留追究法律责任的权利。
  • 相关阅读:
    想要学习编程?不如来玩玩这15款游戏!总有一款适合你!
    C++ 高级教程:C++ 文件和流
    4个小众Chrome插件,最后一个互联网人必备!
    程序员必读,熬夜是如何摧残你的身体的!
    教育部将编程教育纳入中小学相关课程,编程正成为全球语言!
    Windows 比 Linux 好?我有 13 个反对理由
    程序员的十八般兵器库,捋一捋这近几年程序员们日常工作中常用的开源工具
    how to train yolov4 on custom dataset
    How to Perform Object Detection With YOLOv3 in Keras
    YOLOv4 / Scaled-YOLOv4 / YOLO
  • 原文地址:https://www.cnblogs.com/lingyejun/p/15586083.html
Copyright © 2011-2022 走看看