`
bit1129
  • 浏览: 1067988 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【RPC框架Hessian二】Hessian 对象序列化和反序列化

 
阅读更多

 任何一个对象从一个JVM传输到另一个JVM,都要经过序列化为二进制数据(或者字符串等其他格式,比如JSON),然后在反序列化为Java对象,这最后都是通过二进制的数据在不同的JVM之间传输(一般是通过Socket和二进制的数据传输),本文定义一个比较符合工作中。

 

1. 定义三个POJO

   Person类

package com.tom.hessian.common;

import java.io.Serializable;
import java.util.Date;

public class Person implements Serializable{
    private int age;
    private String name;
    /**
     * transient字段不会序列化
     */
    private transient String sensitiveInformation;
    private Date birthDay;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSensitiveInformation() {
        return sensitiveInformation;
    }

    public void setSensitiveInformation(String sensitiveInformation) {
        this.sensitiveInformation = sensitiveInformation;
    }

    public Date getBirthDay() {
        return birthDay;
    }

    public void setBirthDay(Date birthDay) {
        this.birthDay = birthDay;
    }
}

 

   Point类

package com.tom.hessian.common;

import java.io.Serializable;

public class Point implements Serializable{
    private int x;
    private int y;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

 

    ComplexModel

   

package com.tom.hessian.common;

import java.io.Serializable;
import java.util.List;

public class ComplexModel<T> implements Serializable{
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    private Integer id;
    private Person person;
    private List<T> points;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public List<T> getPoints() {
        return points;
    }

    public void setPoints(List<T> points) {
        this.points = points;
    }
}

 

 2. 服务接口

package com.tom.hessian.common;

public interface IComplexModelService {
    
    //持久化
    public void save(ComplexModel model);
    
    //读取
    public ComplexModel read(Integer modelId);
}

 

3. 服务器端代码

package com.tom.hessian.server;

import com.tom.hessian.common.ComplexModel;
import com.tom.hessian.common.IComplexModelService;

import java.util.HashMap;
import java.util.Map;

public class ComplexModelService implements IComplexModelService {
    private Map<Integer,ComplexModel> models = new HashMap<Integer, ComplexModel>();
    @Override
    public void save(ComplexModel model) {
        if (model.getId() == null){
            throw new IllegalArgumentException("id could not be null");
        }

        models.put(model.getId(), model);
    }

    @Override
    public ComplexModel read(Integer modelId) {
        return models.get(modelId);
    }
}

 

4. 客户端代码

package com.tom.hessian.client;

import com.caucho.hessian.client.HessianProxyFactory;
import com.tom.hessian.common.ComplexModel;
import com.tom.hessian.common.IComplexModelService;
import com.tom.hessian.common.Person;
import com.tom.hessian.common.Point;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ComplextModelServiceTest {

    public static void main(String[] args) throws Exception {
        //RPC访问地址
        String url = "http://localhost:8668/web/hessian_complex";

        //接口的动态代理工厂
        HessianProxyFactory factory = new HessianProxyFactory();
        IComplexModelService service = (IComplexModelService) factory.create(IComplexModelService.class, url);

        ComplexModel<Point> model = new ComplexModel<Point>();
        model.setId(1);
        Person person = new Person();
        person.setName("Tom");
        person.setAge(86);
        person.setBirthDay(new Date());
        person.setSensitiveInformation("This should be private over the wire");
        model.setPerson(person);

        List<Point> points = new ArrayList<Point>();
        Point point = new Point();
        point.setX(3);
        point.setY(4);
        points.add(point);

        point = new Point();
        point.setX(100);
        point.setY(100);
        points.add(point);

        //远程方法调用
        model.setPoints(points);
        service.save(model);

        model = service.read(model.getId());
        List<Point> points1 = model.getPoints();
        for(Point elem : points1) {
            System.out.println(elem.getX() + "\t" + elem.getY());
        }

    }

}

 

5. web.xml配置服务

 

6. 运行

启动Jetty,运行ComplextModelTest的main方法,看到如下的异常,表示ComplexModel,Person以及Point都必须可序列化的(实现Serializable接口),

 

 

Exception in thread "main" java.lang.IllegalStateException: Serialized class com.tom.hessian.common.ComplexModel must implement java.io.Serializable
	at com.caucho.hessian.io.SerializerFactory.getDefaultSerializer(SerializerFactory.java:353)
	at com.caucho.hessian.io.SerializerFactory.loadSerializer(SerializerFactory.java:334)
	at com.caucho.hessian.io.SerializerFactory.getSerializer(SerializerFactory.java:234)
	at com.caucho.hessian.io.HessianOutput.writeObject(HessianOutput.java:322)
	at com.caucho.hessian.io.HessianOutput.call(HessianOutput.java:132)
	at com.caucho.hessian.client.HessianProxy.sendRequest(HessianProxy.java:293)
	at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:171)
	at com.sun.proxy.$Proxy0.save(Unknown Source)
	at com.tom.hessian.client.ComplextModelServiceTest.main(ComplextModelServiceTest.java:47)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

 

7. 问题

对于范型的ComplexModel,Hessian是可以正确的序列化和反序列化的,这让我纳闷了,既然范型是编译时的行为,为什么序列化和反序列化能够成功?

 

我的理解:对于JVM而言,运行时没有范型信息,也就是说不管是否使用范型,它的字节码是完全一样的,当把一个没有范型信息的对象序列化为二进制数据,然后再把它反序列回来,它的数据就是反序列化前的样子。因此ComplexModel的List如果是Point类型的元素,那么反序列化后也是Point类型,这属于字节码级别的序列化和反序列化。反序化时为什么能够知道List元素的类型呢?原因是在序列化时,List中的每个元素的类型都会作为序列化的数据的一部分,这部分类型信息就是反序列化到正确类型的依据

 

 

 

 

分享到:
评论

相关推荐

    hessian学习基础篇——序列化和反序列化

    例如,服务器端可以使用Hessian序列化响应数据,客户端则通过反序列化接收到的二进制流来获取对象。这使得通信过程更为高效,尤其在数据量较大时,相比于文本格式,二进制格式能显著减少网络传输时间。 Hessian工具...

    S25-hessian反序列化1

    【S25-Hessian反序列化1】是一个关于Java中Hessian序列化库的讨论,主要涉及Hessian与原生Java序列化的差异以及在Spring框架中的应用。Hessian是一种二进制序列化协议,旨在提高远程过程调用(RPC)的效率。与原生Java...

    Hessian 的字段序列化小记

    - 首先,Hessian序列化器会遍历Java对象的所有字段,对每个字段进行处理。 - 对于基本类型,如int、boolean、double等,Hessian有专门的编码方式,直接将其转换为字节。 - 对于复杂类型如对象和数组,Hessian会...

    hessian序列化规范

    3. 自定义Hessian序列化器以支持自定义类型的序列化和反序列化。 总结,Hessian序列化规范是分布式系统中的重要工具,理解其原理和使用方法,能够帮助我们构建高效、可靠的跨网络通信方案。然而,任何工具都有其...

    Nacos JRaft Hessian 反序列化 RCE 分析.pdf

    - JRaft 使用了 MarshallerHelper 类来处理对象的序列化和反序列化。其中涉及到了对特定类型的 Java 对象进行反序列化处理。 4. **反序列化漏洞**: - 攻击者可以通过构造特殊的 Hessian 数据包,触发 JRaft 中的...

    hessian轻量级 rpc实现

    Hessian RPC的核心在于序列化和反序列化机制。当客户端发起请求时,它会将参数对象序列化成二进制流,通过HTTP POST发送到服务器。服务器端接收到二进制流后,进行反序列化恢复为原始对象,然后执行相应的服务方法,...

    Hessian 2.0序列化协议规范.docx

    Hessian 2.0的目标是提供一种轻量级、易于实现且高效的序列化协议,适用于远程过程调用(RPC)和数据交换。它采用了二进制格式,相比基于文本的序列化协议(如JSON或XML),二进制格式在数据体积和解析速度上都有...

    RPC框架底层模拟

    RPC调用过程中,请求和响应需要在网络间传输,这就涉及到数据的序列化与反序列化。在`RpcFramework.java`中可能会包含实现此功能的代码,如使用JSON、protobuf或Hessian等序列化工具。序列化确保对象能被转换为字节...

    基于netty的手写rpc框架

    4. **序列化与反序列化**:在RPC调用中,数据需要在网络中传输,这就涉及到对象的序列化和反序列化。项目可能使用了如protobuf、json或hessian等序列化工具,将Java对象转换为字节流,以便在网络中传输。 5. **服务...

    浅谈Java序列化和hessian序列化的差异

    Java序列化和Hessian序列化的差异 Java序列化和Hessian序列化是两种常用的序列化机制,它们都可以将对象转换为字节流,以便在网络上传输。但是,两者之间有着很大的差异,今天我们就来比较一下它们的实现机制和特点...

    RPC 框架学习 好的参考学习

    - 序列化模块通常是可插拔的,QiuRPC可能内置支持JSON、Hessian、Protobuf等多种序列化方式,开发者可以根据性能和需求选择合适的序列化库。 5. **负载均衡与容错**: - QiuRPC可能会提供简单的负载均衡策略,如...

    hessian java +c# 数据测试

    这涉及到对Java对象的Hessian序列化,即将Java对象转化为Hessian二进制格式,以便通过网络发送。例如,在HessianDemo中,可能会有一个包含简单数据类型(如int、String)和自定义对象的业务逻辑方法,这些方法可以...

    技术选型分享:JAVA中几种常用的RPC框架介绍.docx

    这些库提供了更高效的序列化和反序列化方案,可以提高数据传输的效率,同时它们通常也支持跨语言通信,因此可以在不同语言的RPC框架中使用。 在选择RPC框架时,需要考虑以下几个关键因素: - **性能**:包括序列化/...

    基于Netty的高性能RPC框架 .zip

    NettyRPC是一个基于Netty构建的高性能Java RPC服务器,支持多种消息序列化方式,如Kryo、Hessian和Protostuff。该项目通过Spring容器管理服务定义和实现,采用主从Reactor线程模型提升服务器并行吞吐性能。 主要...

    如何用Netty写一个自己的RPC框架

    7. 序列化与反序列化:在进行RPC调用时,需要将对象序列化成可以在网络上传输的格式,比如JSON、XML或者更高效的二进制格式。在远程机器接收到数据后,需要将这些数据反序列化成原始的对象。常见的序列化框架包括...

    removal RCE、Hessian 反序列化、Yaml反序列化、密码解密、部分常用敏感路径(漏洞更新截止2024.9.12)

    removal RCE、Hessian 反序列化、Yaml反序列化、密码解密、部分常用敏感路径(漏洞更新截止2024.9.12)

    Hessian应用

    这样,客户端通过网络发送一个Hessian序列化的请求,服务端接收后反序列化为本地对象,然后执行相应的操作,再序列化结果返回给客户端。 在实际应用中,Hessian主要应用于以下场景: 1. **分布式服务调用**:通过...

    自定义rpc框架

    选择合适的序列化框架,如protobuf、Hessian或JSON,对性能有直接影响。 3. **服务注册与发现**:服务提供者在启动时向Zookeeper注册服务,服务消费者通过Zookeeper获取服务地址。 4. **负载均衡**:当有多个服务...

    Hessian

    2. **简单类型支持**:Hessian支持基本的Java数据类型,如整型、浮点型、字符串、日期等,并且可以序列化和反序列化复杂对象。 3. **流式传输**:Hessian协议允许数据分块传输,这意味着服务端可以立即响应部分结果...

Global site tag (gtag.js) - Google Analytics