您的当前位置:首页正文

protoBuf的简单介绍与使用(Java&springboot版本)

2024-12-01 来源:个人技术集锦

protoBuf的简单介绍与使用(Java&springboot)

下面以proto在java项目中的应用作为例子带大家感受

Protocol Buffer 是用于序列化结构化数据的语言中立、平台中立的可扩展机制。
这是官方对它的介绍,

  • 页内目录






一,protoBuf的介绍

官方文档:

protoBuf协议缓冲区是 Google 的语言中立、平台中立、可扩展的序列化结构化数据机制 - 类似于 XML,但更小、更快、更简单。您只需定义一次数据的结构化方式,然后就可以使用特殊生成的源代码,使用各种语言轻松地在各种数据流中写入和读取结构化数据。

Protocol buffers 目前支持 Java、Python、Objective-C 和 C++ 生成的代码。通过我们新的 proto3 语言版本,您还可以使用 Kotlin、Dart、Go、Ruby、PHP 和 C#,以及更多语言。

Protocol buffers 非常适合任何需要以语言中立、平台中立、可扩展的方式序列化结构化、类记录、类型化数据的情况。它们最常用于定义通信协议(与 gRPC 一起)和数据存储。
这里grpc的使用在我的文章列表里面有涉及到有兴趣可以看看;

使用协议缓冲区的一些优点包括:

  • 紧凑的数据存储(易读,易于修改扩展)
  • 快速解析(通过编译生成的代码可以快速调用并解析序列化后编码)
  • 可用于多种编程语言(跨语言,java和c++通讯等等形式)
  • 通过自动生成的类优化功能(也就是通过插件生成对应的序列化,反序列化代码用于高效的开发)

通常在工作中称其为 pb ,那么我下文也以pb称呼

二,pb的特点

协议缓冲区是一种用于序列化结构化数据的方法,可以有效地将数据打包为二进制格式,以便在网络中传输或进行长期存储。该格式适用于短暂的网络流量和长期数据存储,因为它可以快速地序列化和反序列化数据,同时还可以使用新信息进行扩展,而不会使现有数据无效或需要更新代码。

短暂的网络流量解释:在实时网络通信中,数据需要在短时间内进行传输和接收。协议缓冲区可以将数据快速地序列化为二进制格式,以便在网络中传输和接收,从而提高通信效率。
长期数据存储解释:在某些情况下,需要将数据长期存储在磁盘或数据库中,以便后续访问和使用。协议缓冲区可以将数据打包为二进制格式,从而减少存储空间和访问时间,同时还可以保证数据的完整性和一致性。

协议缓冲区的优点包括:
1、高效性:协议缓冲区可以将数据打包为二进制格式,从而减少了网络传输和存储的空间和时间。
2、可扩展性:协议缓冲区可以使用新信息进行扩展,而无需更改现有数据的格式或代码。这使得协议缓冲区非常灵活,可以适应不断变化的需求。
3、易于使用:协议缓冲区可以使用标准工具进行序列化和反序列化操作,从而使开发人员可以更加轻松地使用该格式。
4、可靠性:协议缓冲区可以确保数据在传输和存储过程中的完整性和一致性,从而避免了数据损坏或丢失的问题。
总之,协议缓冲区是一种非常有用的技术,可以有效地处理结构化数据,并提供可扩展性和可靠性,适用于各种网络应用和长期数据存储需求。

三, proto3的数据类型

我们可以使用下面的数据类型来声明.proto的类型

四,protoBuf的基本语法

类似于java的语法,一个message单元会生成一个java对象;
具体支持哪些语法可以关注一下官方文档

五,proto文件定义和构成

syntax = "proto3";//声明proto语法版本

package com.my.start.myKnowledge.pb;//定义该类生成的包位置
option java_multiple_files = true;//是否再使用protobuf编译工具的时候将该proto文件编译成一个类;


message SearchInfo{
  int32 num = 1;//数字
  string uuid = 2;//字符串
  Sex sex = 3;//枚举
  PosInfo baseInfo = 4;//对象
  repeated Hobby hobbies = 5;//集合
}

message PosInfo{
  string address = 1;
  string desc = 2;
}
message Hobby{
  string name = 1;
  string desc = 2;
}
enum Sex{
  BOY = 0;
  GIRL = 1;
}
六,proto文件的编译

依赖maven
在pom文件中引入依赖和插件

<dependencies>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.24.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <version>3.24.0</version>
        </dependency>
</dependencies>

    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.5.0.Final</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}</protocArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

compile代码,出现protobuf的插件即可


至此,我们就可以开始使用protobuf进行传输解析数据了;

七、bulid数据和解析数据
    //客户端和服务端使用相同的pb进行编译
    
    //1、客户端构造数据
    SearchInfo build = SearchInfo.newBuilder()
            .setNum(117).setUuid("sadasdadsacf-xxxq").setSex(Sex.BOY)
            .setBaseInfo(PosInfo.newBuilder().setAddress("yanan").setDesc("luochuan").build())
            .addAllHobbies(Lists.newArrayList(
                    Hobby.newBuilder().setName("basketball").build(),
                    Hobby.newBuilder().setName("chicken").build()
            )).build();
    byte[] bytes = build.toByteArray();
    
    //2、客户端数据发送数据,发送数据的形式不限于是tcp,udp,mq等传输字节组的形式
    //xxxxx
    
    //3、服务端解析数据 
    SearchInfo searchInfo = SearchInfo.parseFrom(bytes);
显示全文