protobuf(java)

1.介绍

序列化需要考虑?
1.序列化之后的码流大小(占用网络带宽)
2.序列化和反序列化的性能(CPU资源占用)
3.是否支持跨语言

protobuf:
1.不需要序列化与类相关的信息
2.动态伸缩性(比如int可能根本就用不到4个字节,可能2个字节就能表示数据了)
int 4字节(java) -> 1~5字节(protobuf)

1.1 Java序列化

Java对象的序列化和反序列化
Person

public class Person implements Serializable{

    private static final long serialVersionUID = 2690623243047210668L;

//    基本类型不会被序列化,但会被自动封装为包装类
//    所有数据类型包装类都是可序列化的
    private Integer pid;
    private String pname;
    private Double score;

    public Integer getPid() {
        return pid;
    }

    public void setPid(Integer pid) {
        this.pid = pid;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Person{");
        sb.append("pid=").append(pid);
        sb.append(", pname='").append(pname).append('\'');
        sb.append(", score=").append(score);
        sb.append('}');
        return sb.toString();
    }
}

TestSerial

public class TestSerial {
    //序列化
    @Test
    public void SerializePerson() throws Exception{
        Person person = new Person();
        person.setPid(1);
        person.setPname("小明");
        person.setScore(98.8);
        // ObjectOutputStream 对象输出流,将Person对象存储到E盘的Person.txt文件中,完成对Person对象的序列化操作
        ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
                new File("E:/Person.txt")));
        oo.writeObject(person);
        System.out.println("Person对象序列化成功!");
        oo.close();
    }

    //反序列化
    @Test
    public void DeserializePerson() throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                new File("E:/Person.txt")));
        Person person = (Person) ois.readObject();
        System.out.println("Person对象反序列化成功!");
        System.out.println("person = " + person.toString());


    }

    @Test
    public void SerializeAndDeserialize() throws IOException, ClassNotFoundException {
        Person person = new Person();
        person.setPid(1);
        person.setPname("小明");
        person.setScore(98.8);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(person);
        byte[] bytes = bos.toByteArray();
        System.out.println("bytes = " + Arrays.toString(bytes));
        System.out.println("序列化成功!!!");
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
        Person personNew = (Person)ois.readObject();
        System.out.println("反序列化成功!!!");
        System.out.println("personNew = " + personNew.toString());


    }

}

在这里插入图片描述

2.使用

在这里插入图片描述

2.1 IDEA配置

1.安装插件,然后重启一下
在这里插入图片描述

2.2 添加依赖pom

     <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <!--添加protobuf依赖-->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.5.1</version>
        </dependency>

    </dependencies>

    <!--配置Maven插件-->
    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.4.1.Final</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.0</version>
                <configuration>
                    <protocArtifact>
                        com.google.protobuf:protoc:3.5.1:exe:${os.detected.classifier}
                    </protocArtifact>
                    <pluginId>grpc-java</pluginId>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

2.3 编写protobuf配置文件person.proto

syntax = "proto3";//指定使用语法
option java_package = "com.zy.protobuf";//指定包路径
option java_outer_classname = "PersonModel";//指定外部类名字

message Person {//内部类名字,注意和java_outer_classname区分
    int32 pid = 1;
    string pname = 2;
    double score = 3;
}

2.4 在src\main\创建proto目录,并把配置文件存放于此

因为编译的时候,插件会默认在这个目录下查找配置文件
注意:
proto必须要设置成源代码目录
在这里插入图片描述
在这里插入图片描述

2.5 编译

编译完后,可以把proto目录给还原回去,并且把插件给注释掉,不然下次整体编译会报错,我们只需要生成的java文件即可
在这里插入图片描述

2.6 运行

TestProto

public class TestProto {
    //序列化
    private byte[] serialize(){
        PersonModel.Person.Builder builder = PersonModel.Person.newBuilder();
        builder.setPid(2);
        builder.setPname("德玛");
        builder.setScore(88.9);

        PersonModel.Person person = builder.build();
        return person.toByteArray();
    }

    //反序列化
    private PersonModel.Person deserialize(byte[] data) throws Exception {
        PersonModel.Person person = PersonModel.Person.parseFrom(data);
        return person;
    }

    @Test
    public void test1() throws Exception {
        byte[] serialize = serialize();
        System.out.println("序列化成功!!!");
        System.out.println("bytes = " + Arrays.toString(serialize));
        PersonModel.Person person = deserialize(serialize);
        System.out.println("反序列化成功!!!");
        System.out.println("person = " + person.getPid()+"*"+person.getPname()+"*"+person.getScore());
    }
}

在这里插入图片描述
从上面可知,字节数组少了许多,这是因为protobuf把描述类的信息都加在了之前生成的PersonModel类里了,传输过程中只传必要的信息

参考

protobuf使用详解
protobuf 编码实现解析(java)
maven集成Protobuff并创建GRpc示例
添加链接描述
用Maven实现一个protobuf的Java例子
Intellij IDEA中使用Protobuf的正确姿势
protobuf 消息升级 && 动态proto
d_d

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值