关于dubbo:Dubbo使用Hessian2序列化时针对Byte类型出现javalangClassCastException

36次阅读

共计 2276 个字符,预计需要花费 6 分钟才能阅读完成。

背景

前不久翎野君帮共事看一个问题,比拟有启发性,特记录一下。一个 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 官网文档:Hessian 2.0 Serialization Protocol

 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> 等尽量避免应用。

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

正文完
 0