Protobuf 在 Java 中的入门实例

心已赠人 2023-06-24 11:25 114阅读 0赞

Protobuf1 是一种语言中立、平台无关、可扩展的序列化数据的格式,可用于通信协议,数据存储等。

本文将演示在 Java 语言中如何编写一个 Protobuf 的入级程序,也许你可能并不了解 Protobuf,这没有关系,基于 Protobuf 官方文档的衍生博文已经安排上了,只是限于内容较多,我正在一点点写作中,让我们先来简单实战吧!

注: 本文及后续所有关于 Protobuf 相关文章均采用 Protobuf3 版本,具体为 Protobuf 3.11.0

源码地址:https://github.com/jitwxs/blog\_sample

一、插件

工欲善其事,必先利其器!让我们先在全宇宙第一的 Java IDE 中安装上 Protobuf 的插件。在插件市场中搜索并安装 Protobuf Support,或下载离线插件包手动安装: https://plugins.jetbrains.com/plugin/8277-protobuf-support/ 。

Protobuf Support Plugins

安装完毕后,创建一个空的 Maven 工程。借助于 Protobuf Maven 插件的功劳,使我们不必在本地搭建 Protobuf 环境。直接编辑 Pom 文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. ...
  4. <properties>
  5. <protobuf.version>3.11.0</protobuf.version>
  6. </properties>
  7. <dependencies>
  8. <dependency>
  9. <groupId>com.google.protobuf</groupId>
  10. <artifactId>protobuf-java</artifactId>
  11. <version>${protobuf.version}</version>
  12. </dependency>
  13. </dependencies>
  14. <build>
  15. <extensions>
  16. <extension>
  17. <groupId>kr.motd.maven</groupId>
  18. <artifactId>os-maven-plugin</artifactId>
  19. <version>1.6.2</version>
  20. </extension>
  21. </extensions>
  22. <plugins>
  23. <plugin>
  24. <groupId>org.xolstice.maven.plugins</groupId>
  25. <artifactId>protobuf-maven-plugin</artifactId>
  26. <version>0.6.1</version>
  27. <configuration>
  28. <protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}</protocArtifact>
  29. </configuration>
  30. </plugin>
  31. </plugins>
  32. </build>
  33. </project>

首先我们引入了 protobuf-java 的 Java 包依赖,然后引入了两个 Maven 插件:

  • os-maven-plugin2 获取当前运行环境的系统信息,作为辅助插件。
  • protobuf-maven-plugin 负责将 protobuf 文件转换为 Java 类。<protocArtifact> 内容是 protobuf 转化为 Java 类的执行文件的配置信息,由于 ${os.detected.classifier} 可以自动识别当前环境的操作系统信息,自动适配不同操作系统,因此无需修改。

二、Protobuf 源文件

protobuf-maven-plugin 插件默认会扫描 src/main/proto 下的 protobuf 文件,因此我们需要将 protobuf 文件放置在该目录下。如果你想放置在其他地方,请手动修改 maven 插件的 <protoSourceRoot>3 属性。

首先创建一个关于性别的 Protobuf 枚举类 sex_enum.proto,用于标识男女:

  1. syntax = "proto3";
  2. option java_package = "jit.wxs.demo.enums";
  3. option java_outer_classname = "SexEnumProto";
  4. enum SexEnum {
  5. INVALID = 0;
  6. MALE = 1;
  7. FEMALE = 2;
  8. }
  • syntax = "proto3";:指定使用 Protobuf3 进行编译,不写默认使用 Protobuf2 编译。
  • option java_package:指定生成 Java 类后的所属包。
  • option java_outer_classname = "SexEnumProto";:指定生成 Java 类后的类名。

关于枚举类,有以下几点说明:

  • 枚举值序号必须从 0 开始。
  • 序号为 0 的枚举值必须是第一个元素。
  • 为 0 的枚举值是该枚举类的默认值。

然后再创建一个用户 Protobuf 类 user.proto

  1. syntax = "proto3";
  2. option java_package = "jit.wxs.demo.dto";
  3. option java_outer_classname = "UserProto";
  4. import "sex_enum.proto";
  5. message User {
  6. int32 age = 1;
  7. string name = 2;
  8. SexEnum sex = 3;
  9. }
  • import "sex_enum.proto"; 表示将 sex_enum.proto 类引入到当前文件中,以便调用。
  • age:年龄数据类型为 int32,默认值为 0,在 Java 中是 int 类型。
  • name:姓名数据类型是 string,默认值为空串,在 Java 中数据类型是 String 类型。
  • sex:性别数据类型为 SexEnum 类型,默认值为 INVALID。

目录结构如下:

20191223011801327.png_pic_center

三、生成 Java 类

在 IDEA 中,双击 Maven Protobuf 插件的 protobuf:complie选项,在项目的 target 文件夹中就会生成 protobuf 文件对应的 Java 类,如下图所示。

Protobuf Compile

四、运行

将生成的两个 Java 类移动(不要复制,否则运行会报文件名重复错误)到项目的 java 目录下(保持 package 的正确性),然后编写一个测试类测试下。

  1. package jit.wxs.demo.test;
  2. import com.google.protobuf.InvalidProtocolBufferException;
  3. import jit.wxs.demo.dto.UserProto;
  4. import jit.wxs.demo.enums.SexEnumProto;
  5. import java.util.Arrays;
  6. /** * 测试 ProtoBuf 序列化与反序列化 * @author jitwxs * @date 2019年12月20日 1:22 */
  7. public class ProtoBufTest {
  8. public static void main(String[] args) {
  9. UserProto.User.Builder builder = UserProto.User.newBuilder();
  10. builder.setName("zhangsan");
  11. builder.setAge(18);
  12. builder.setSex(SexEnumProto.SexEnum.MALE);
  13. UserProto.User user = builder.build();
  14. System.out.println("before: " + user.toString());
  15. byte[] byteArray = user.toByteArray();
  16. System.out.println("=======");
  17. System.out.println("User Byte: " + Arrays.toString(byteArray));
  18. System.out.println("=======");
  19. try {
  20. UserProto.User user2 = UserProto.User.parseFrom(byteArray);
  21. System.out.println("after: " + user2.toString());
  22. } catch (InvalidProtocolBufferException e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. }

运行结果如下:

  1. before: age: 18
  2. name: "zhangsan"
  3. sex: MALE
  4. =======
  5. User Byte: [8, 18, 18, 8, 122, 104, 97, 110, 103, 115, 97, 110, 24, 1]
  6. =======
  7. after: age: 18
  8. name: "zhangsan"
  9. sex: MALE

最终项目的目录结构如下:

2019122301234225.png_pic_center


  1. Google Protocol Buffers,协议缓冲区。 ↩︎
  2. https://github.com/trustin/os-maven-plugin ↩︎
  3. https://www.xolstice.org/protobuf-maven-plugin/index.html ↩︎

发表评论

表情:
评论列表 (有 0 条评论,114人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Protobuf入门

    Protobuf入门 Protobuf是一个灵活,高效,结构化的数据序列化框架,相比于XML等传统的序列化工具,它更小,更快,更简单。Protobuf支持数据结构化一次可以