You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ByteArray进行对象序列化反序列化跨运行时类型异常求助

问题根因

你代码里有3个核心错误,直接导致了跨环境反序列化类型异常:

  • 第一个也是最严重的错误:批量入库逻辑写死了所有记录的blob内容
    看写入代码逻辑:你先把当前方法入参里的单个invocationData的参数、返回值序列化生成字节数组,再把invocationData加入缓存列表,等缓存满了批量入库的时候,循环所有缓存的记录,但是所有记录都复用了最开始生成的那一份字节数组,也就是说除了第一个触发批量写入的记录之外,其他所有记录存的blob都是错的。同一运行时你大概率是缓存大小设为1,每次批量入库只有1条记录,刚好碰对结果,跨环境运行缓存被填满多几条记录就全乱了,自然类型对不上。
  • 第二个错误:序列化和反序列化的API不匹配
    你写入返回值的时候用的是writeObject()方法,如果返回值是基本类型,writeObject()会自动装箱为对应的包装类(比如boolean转Boolean)再序列化,序列化结果里带的是对象的元信息。但是你反序列化的时候,碰到boolean类型就调用readBoolean()读基本类型,这个API是对应writeBoolean()的写入结果的,和writeObject()写入的装箱对象结构完全不匹配,读出来的值自然是错的。
  • 第三个错误:读取输入参数字节数组的逻辑有截断风险
    你读取参数blob的时候用available()判断长度,这个方法返回的是当前可无阻塞读取的字节数,不是整个blob的总长度,很容易导致字节数组长度不够,序列化数据被截断,反序列化自然出错。

修复方案

  1. 先修批量写入的bug:把参数、返回值的序列化逻辑移到循环内部,每条记录单独生成自己的blob字节数组,或者把序列化后的字节数组存到InvocationData对象里,不要在循环外公用同一个字节数组变量。
  2. 统一反序列化API:所有返回值都用readObject()读取,读完之后再根据返回类型做拆箱即可,示例代码:
// 反序列化返回值部分修改为
rvIn = new ObjectInputStream(rvBis);
Object rawObj = rvIn.readObject();
switch (returnType) {
    case "boolean":
        returnValue = (Boolean) rawObj;
        break;
    case "int":
        returnValue = (Integer) rawObj;
        break;
    // 其他基本类型同理做拆箱转换
    default:
        returnValue = rawObj;
        break;
}
  1. 修复参数读取逻辑,直接用rs.getBytes()读取完整的blob字节数组,不要用流读:
// 输入参数读取部分修改为
byte[] inputArgsByteArray = rs.getBytes(5);
ByteArrayInputStream bis = new ByteArrayInputStream(inputArgsByteArray);

内容的提问来源于stack exchange,提问作者alectogeek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 03:36:07