最近忙于业务迭代开发,没有太多时间思考。这两天,开发的时候遇到了一个hessian 序列化异常,拿出来记录一下分析的过程及解决方法。
先上异常,
2016-06-01 10:59:37 New I/O server worker #1-1 WARN [com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation:112] - [DUBBO] Decode argument failed: com.apricotforest.casefolder.medical.search.vo.MedicalRecordSearchVo.tagId: expected integer at 0x24 [B ([B@1e919697), dubbo version: 2.5.3, current host: 192.168.10.23com.alibaba.com.caucho.hessian.io.HessianFieldException: com.apricotforest.casefolder.medical.search.vo.MedicalRecordSearchVo.tagId: expected integer at 0x24 [B ([B@1e919697) at com.alibaba.com.caucho.hessian.io.JavaDeserializer.logDeserializeError(JavaDeserializer.java:671) at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectFieldDeserializer.deserialize(JavaDeserializer.java:400) at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:233) at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:157) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2067) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1592) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1576) at com.alibaba.dubbo.common.serialize.support.hessian.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:94) at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:109) at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:71) at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCodec.decodeBody(DubboCodec.java:137) at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:126) at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:87) at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCountCodec.decode(DubboCountCodec.java:46) at com.alibaba.dubbo.remoting.transport.netty.NettyCodecAdapter$InternalDecoder.messageReceived(NettyCodecAdapter.java:134) at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:80) at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559) at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274) at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261) at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:349) at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:280) at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:200) at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108) at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:44) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected integer at 0x24 [B ([B@1e919697) at com.alibaba.com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2720) at com.alibaba.com.caucho.hessian.io.Hessian2Input.expect(Hessian2Input.java:2691) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readInt(Hessian2Input.java:773) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readType(Hessian2Input.java:2296) at com.alibaba.com.caucho.hessian.io.BasicDeserializer.readObject(BasicDeserializer.java:251) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1696) at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectFieldDeserializer.deserialize(JavaDeserializer.java:396) ... 26 more
看到这段异常,分分钟想到了dubbo序列化默认用的是hessian,而hessian处理复杂对象时爆出的异常,不太好理解,于是写出一个测试类模拟了一下hessian 序列化/反序列化
package com.apricotforest.casefolder.medical.utils; import com.alibaba.com.caucho.hessian.io.HessianSerializerInput; import com.alibaba.com.caucho.hessian.io.HessianSerializerOutput; import com.apricotforest.casefolder.medical.search.vo.MedicalRecordSearchVo; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; /** * Created by on 16/5/31. */ public class HessianSerializeUtil { /** * 纯hessian序列化 * * @param object * @return * @throws Exception */ public static byte[] serialize(Object object) throws Exception { if (null == object) { throw new NullPointerException(); } ByteArrayOutputStream os = new ByteArrayOutputStream(); HessianSerializerOutput hessianOutput = new HessianSerializerOutput(os); hessianOutput.writeObject(object); return os.toByteArray(); } /** * 纯hessian反序列化 * * @param bytes * @return * @throws Exception */ public static Object deserialize(byte[] bytes) throws Exception { if (bytes == null) { throw new NullPointerException(); } ByteArrayInputStream is = new ByteArrayInputStream(bytes); HessianSerializerInput hessianInput = new HessianSerializerInput(is); Object object = hessianInput.readObject(); return object; } public static void main(String[] args) throws Exception { byte[] bytes; // String[] arr = {"6eb90e77-f37-4daf-8665-fc56951f9a25", // "aedf9088-899c-4200-940e-72215b38d258","6142DD32-485A-4393-B757-24B8DC043E99"}; String[] arr = new String[]{"4e2a6912-f4b9-4e04-a999-982ef2bcc64f", "88f4fcc6-43ef-4ccb-8a1a-d50d59313d3a"}; MedicalRecordSearchVo searchVo = new MedicalRecordSearchVo() .setKeyword("ddd").setUserId(2100000005).setTagId(arr); bytes = HessianSerializeUtil.serialize(searchVo); System.out.println("序列化后对象:" + bytes); System.out.println("反序列化后正常属性: " + ((MedicalRecordSearchVo) HessianSerializeUtil.deserialize(bytes)).getKeyword()); System.out.println("反序列号后数组属性: " + ((MedicalRecordSearchVo) HessianSerializeUtil.deserialize(bytes)).getTagId()[0]); } }
本地序列化后,发现数据可以正常反序列化,深入异常,查看异常所对应的代码块,调用栈如下
仔细查看服务调用方传过来的数据,发现类型不匹配导致,升级依赖客户端即可
ps:dubbo 接口联调过程,需要在本地联调,但是本地环境和开发环境共用一个zk,所以使用dubbo 控制台,对开发环境接口降权或添加白名单策略
相关推荐
- 首先,Hessian序列化器会遍历Java对象的所有字段,对每个字段进行处理。 - 对于基本类型,如int、boolean、double等,Hessian有专门的编码方式,直接将其转换为字节。 - 对于复杂类型如对象和数组,Hessian会...
当服务端出现异常时,Hessian会将异常信息序列化并返回给客户端,客户端可以根据这些信息进行错误处理。 7. **版本兼容性**: 随着服务的升级和扩展,需要考虑版本兼容性问题。Hessian提供了一定的兼容性策略,但...
此外,对于序列化异常,可能需要检查对象是否可序列化,或者使用Hessian的自定义序列化类。 总的来说,Spring与Hessian的集成提供了便捷的远程调用方案,但需要注意性能优化、安全性以及故障排查。通过深入学习和...
Java序列化是Java平台内建的一种对象持久化机制,它允许我们将对象的状态转换为字节流,以便存储或在网络上传输。Netty,一个高性能、异步事件驱动的网络应用程序框架,广泛应用于分布式系统和高并发场景。在Netty中...
通过研究这些文件,开发者可以直接看到问题的现象,理解问题的上下文,并尝试各种解决方案,如更新Hessian到兼容的版本、调整Spring配置、修复序列化类或者优化异常处理逻辑。 总的来说,Hessian 4.0.7与Spring ...
Hessian的目标是提供一个轻量级、高效的序列化和通信机制,使得对象能够在网络间透明地进行传输。在这个案例代码中,我们将探讨Hessian如何工作以及如何在实际项目中应用。 首先,Hessian协议的特点在于它的二进制...
- 在调用过程中,需要捕获可能的网络错误、序列化/反序列化异常等。 - 实现适当的错误处理逻辑,如重试、通知用户或记录日志。 5. **性能优化**: - 注意网络连接的复用,避免频繁创建和关闭连接。 - 对于大量...
在这个过程中,开发者需要注意的是,虽然Hessian协议提供了自动类型映射,但有时仍需自定义序列化和反序列化的逻辑,特别是在处理自定义对象或者特殊数据结构时。 在实际应用中,Hessian常用于构建轻量级的分布式...
当出现错误时,Hessian会尝试捕获并序列化异常,以便在客户端恢复。 7. **性能优化**:在大型分布式系统中,Hessian的性能优化至关重要。这可能包括缓存策略、连接池管理、以及对网络延迟和带宽的优化。 8. **工具...
为了能够通过Hessian进行序列化和反序列化,实体类需要遵循特定的规则,例如字段类型要简单,避免复杂的嵌套结构。 3. **服务发布**: - 在服务器端,需要将实现类绑定到一个特定的URL,以便客户端可以通过该URL...
3. 调用:通过代理对象调用服务接口的方法,Hessian会自动完成网络通信和序列化/反序列化操作。 五、示例——rpc4j-sample-web "rpc4j-sample-web"这个压缩包文件很可能是Hessian RPC的一个示例项目。通常,它会...
这意味着 Nacos 使用 Hessian 来序列化和反序列化对象,但并没有正确地设置白名单来限制哪些类可以被反序列化。这为攻击者提供了利用的机会,通过构造恶意的序列化数据包,可以在目标系统上执行任意代码。 #### ...
Hessian是一种二进制协议,由Caucho Technology开发,主要设计用于远程方法调用(Remote Method Invocation,RMI)和服务端方法的序列化。在Android平台上,Hessian被广泛应用于构建轻量级、高效的跨网络通信解决...
通过阅读源码,开发者可以了解Hessian如何实现高效的序列化和反序列化,以及它是如何处理网络通信的。源码也使得开发者能够根据需要修改或扩展Hessian的功能,例如添加新的序列化策略,或者优化特定场景下的性能。 ...
Hessian处理了底层的序列化和反序列化,使得Java对象能够以透明的方式在网络间传递。这极大地简化了分布式系统的开发,并且减少了网络开销,因为Hessian的二进制格式通常比基于文本的协议(如XML-RPC或SOAP)更紧凑...
3. **内置序列化**:Hessian内置了对象序列化机制,可以直接将Java对象转换为二进制流,无需额外的序列化接口实现。 4. **简单API**:Hessian提供简洁的API,使得开发者可以快速集成到项目中,创建和调用远程服务。 ...
1. **序列化和反序列化**:Hessian协议的核心在于将Java对象转换成二进制流(序列化)和从二进制流恢复对象(反序列化)。这需要对Java的反射API有深入的理解,以便获取和设置对象的字段值。 2. **类型编码**:...
1. 理解Hessian序列化和反序列化的机制,包括基本类型和自定义类型的处理。 2. 学习如何在Java项目中配置和使用Hessian客户端和服务端。 3. 掌握如何通过Hessian源码调试和优化性能。 4. 熟悉Hessian与其他通信协议...
8. **错误处理**:当发生错误时,Hessian会将异常信息序列化并发送回客户端,使得客户端可以根据这些信息进行相应的错误处理。 9. **版本兼容性**:Hessian协议有一定的版本管理,新版本可以向后兼容旧版本,以确保...
1. **源码文件**:包含了Hessian的核心实现,包括序列化和反序列化的算法,以及与其他网络协议的接口。 2. **示例代码**:这些示例可以帮助我们理解如何在实际项目中使用Hessian,包括创建服务端、客户端,以及调用...