在进行dubbo开发中遇到一个问题,当是用hession2进行序列化时,子类和父类有相同的字段时,hession2反序列化获取不到该字段数据,如下:
import java.io.Serializable; import java.util.Date; public class User implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String userId; private String userName; private Date addDate; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public Date getAddDate() { return addDate; } public void setAddDate(Date addDate) { this.addDate = addDate; } }
import java.util.Date; public class ChildrenUser extends User { /** * */ private static final long serialVersionUID = 1L; private String userId; private Date addDate; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public Date getAddDate() { return addDate; } public void setAddDate(Date addDate) { this.addDate = addDate; } @Override public String toString() { return "ChildrenUser [userId=" + userId + ", addDate=" + addDate + "]"; } }
测试程序如下:
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Date; import com.alibaba.com.caucho.hessian.io.Hessian2Input; import com.alibaba.com.caucho.hessian.io.Hessian2Output; import com.pinganwj.clinic.api.demo.domain.ChildrenUser; import com.pinganwj.clinic.api.demo.domain.User; public class TestHessionLite1 { public static void main(String[] args) throws IOException { User user=new ChildrenUser(); user.setAddDate(new Date()); user.setUserId("123"); user.setUserName("呵呵"); byte[] aa=TestHessionLite1.serialize(user); Object mm=TestHessionLite1.deserialize(aa); System.out.println(mm.toString()); } 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) throws IOException{ 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; } }
运行该测试程序,输出如下
ChildrenUser [userId=null, addDate=null]
然后我再是用kryo来进行序列化,
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.Serializable; import java.util.Date; import org.apache.commons.codec.binary.Base64; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import com.esotericsoftware.kryo.serializers.JavaSerializer; import com.pinganwj.clinic.api.demo.domain.ChildrenUser; import com.pinganwj.clinic.api.demo.domain.User; public class TestKryo1 { public static void main(String[] args) { User user=new ChildrenUser(); user.setAddDate(new Date()); user.setUserId("123"); user.setUserName("呵呵"); String aa=TestKryo1.serialize(user); Object mm=TestKryo1.deserialize(aa,User.class); System.out.println(mm.toString()); } private static <T extends Serializable> String serialize(T obj) { Kryo kryo = new Kryo(); kryo.setReferences(false); kryo.register(obj.getClass(), new JavaSerializer()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Output output = new Output(baos); kryo.writeClassAndObject(output, obj); output.flush(); output.close(); byte[] b = baos.toByteArray(); try { baos.flush(); baos.close(); } catch (IOException e) { e.printStackTrace(); } return new String(new Base64().encode(b)); } @SuppressWarnings("unchecked") private static <T extends Serializable> T deserialize(String obj, Class<T> clazz) { Kryo kryo = new Kryo(); kryo.setReferences(false); kryo.register(clazz, new JavaSerializer()); ByteArrayInputStream bais = new ByteArrayInputStream( new Base64().decode(obj)); Input input = new Input(bais); return (T) kryo.readClassAndObject(input); } }
输出结果如下:
ChildrenUser [userId=123, addDate=Fri Aug 25 00:28:45 CST 2017]
输出正确。
这个是hession2的一个坑,经过查看源码Hessian2Input类中的readObjectInstance方法
他将父类的属性都读取了
而每次第一次能读取到值,然后第二次读取就是null,都被覆盖了,所以输出都是null。
所以解决方案就是去掉子类中的字段或者父类中的字段,或者改用kryo等其他序列化方式。
相关推荐
在IT行业中,分布式服务框架是实现大规模系统高可用、高性能的关键技术之一,而Dubbo、Hessian和RMI则是其中的三个重要组件。本篇将深入解析这些技术及其在实际应用中的示例。 首先,Dubbo是阿里巴巴开源的一款高...
Hessian是一种高效的序列化协议,它将Java对象转换为二进制流,通过网络传输,然后在另一端还原为原来的对象。相比基于文本的XML或JSON,Hessian传输的数据量更小,性能更高。 在Dubbo中,Hessian协议被用于服务间...
4. **类型安全**:Hession在序列化过程中保留了类型信息,避免了因为类型转换导致的问题。 5. **动态接口**:Hession支持动态接口,服务端无需预先定义接口,客户端可以动态发现并调用服务。 **Hession的工作流程:...
Dubbo支持多种序列化方式,如Hession、JSON等,以提高传输效率和兼容性。 **服务治理的需求** 随着服务数量的增长,服务治理的重要性凸显: 1. **服务链路跟踪和监控**:当服务调用链路变长,需要追踪服务间的调用...
2. RMI 协议:采用 JDK 标准的 RMI 协议实现,传输参数和返回参数对象需要实现 Serializable 接口,使用 Java 标准序列化机制,使用阻塞式短连接,传输数据包大小混合,消费者和提供者个数差不多,可传文件,传输...
2. **自动类型转换**:Hessian-lite能够自动处理Java对象到二进制流的序列化和反序列化,无需开发者手动进行类型转换,简化了开发流程。 3. **紧凑的字节码表示**:通过高效的编码方式,Hessian-lite可以将常见的...
4. **反序列化**:服务端接收到请求后,将数据还原为可处理的对象。 5. **执行服务**:服务端执行对应的服务逻辑。 6. **返回结果**:服务端将执行结果序列化并返回给客户端。 7. **反序列化并处理**:客户端接收...
在服务端接收到请求后,会将这些二进制数据反序列化回原始对象,执行相应的方法并返回结果。 4. **类型映射**:Hessian支持多种数据类型,包括基本类型、自定义对象等。在跨语言通信时,Hessian会自动处理类型映射...
3. Dubbo 底层使用 Netty 框架,基于 TCP 协议传输,配合 Hession 序列化完成 RPC 通信 4. Spring Cloud 是基于 Http 协议+Rest 接口调用远程过程的通信 Dubbo 是一个高性能、轻量级的开源 RPC 框架,提供了分布式...
1. **高性能**:HSF采用了高效的序列化协议和网络通信框架,如Hession和Dubbo的Netty,确保了服务调用的低延迟和高吞吐量。 2. **服务治理**:HSF提供服务注册、发现、路由、负载均衡、熔断、降级等全面的服务治理...
理解通信协议传输过程中的序列化和反序列化机制 基于框架的RPC通信技术 WebService/ApacheCXF RMI/Spring RMI Hession 传统RPC技术在大型分布式架构下面临的问题 分布式架构下的RPC解决方案 Zookeeper ...
序列化 nIo 匿名类 包装类 优先级 引用 语言工具类库 容器类 集合 链表 map 工具类 系统类 日期类 数字类 字符串+正则 流 字符流 字节流 语言特性 继承 封装 多态 JVM 多线程与并发 GC...