Java中简单使用Protobuf

424 阅读2分钟

Java中简单使用Protobuf

protobuf作为google开源的序列化框架,与语言无关,具有平台无关、可扩展等特性,相对于JSON,具有体积小、速度快等优点

不了解Protobuf定义和类型的小伙伴,可以查看上一篇文章 -> 初识Protobuf

下面会使用一个简单的案例,来介绍Protobuf在Java中的使用

定义Proto文件

  • 这里采用proto3的语法定义

    syntax = "proto3"; // 定义proto版本,如果没有指定proto版本,则采用proto2进行编译,proto2和proto3语法上有些差异
    
    package test; // 相当于定于命名空间,防止不同的消息类型存在命名冲突
    
    option java_package = "org.example.proto"; // 输出的包的名称
    option java_outer_classname = "HeroProto"; // 编译之后输出的文件名称,即直接使用的类名称,如果没有定义,则采用文件名称的驼峰命名作为生成的类名称
    
    message GaiLun {
        string hero_name = 1; // 名称
        int32 level = 2; // 等级
        repeated string skill = 3; // 技能列表
        string goods = 4; // 装备
        Group group = 5; // 分组
    }
    
    message LiBai {
       string hero_name = 1; // 名称
       int32 level = 2; // 等级
       repeated string skill = 3; // 技能列表
       string goods = 4; // 装备
       string friend = 5; // 队友
       Group group = 6; // 分组
    }
    
    // 枚举
    enum Group {
        blue_group = 0;
        red_group = 1;
    }
    
  • 通过protoc.exe编译vboot_hero.proto文件为java文件

    protoc.exe --java_out=. vboot_hero.proto

    就会将java源代码生成到当前目录下,文件中指定的包名中

  • 复制HeroProto.java到项目的指定目录下

Maven依赖

  • pom.xml中增加proto依赖

    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>3.4.0</version>
    </dependency>
    
    <!--如果需要对proto的message进行格式化输出,加入工具类支持-->  
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java-util</artifactId>
        <version>3.5.0</version>
    </dependency>
    

使用Proto对象

  • 创建Proto对象

    public class ProtoMain {
    
        public static void main(String[] args) throws InvalidProtocolBufferException {
            // 使用proto
    
            HeroProto.GaiLun.Builder gailunBuilder = HeroProto.GaiLun.newBuilder();
            gailunBuilder.setHeroName("盖伦");
            gailunBuilder.addAllSkill(Arrays.asList("Q", "W", "E", "R"));
            gailunBuilder.setLevel(18);
            gailunBuilder.setGoods("无尽之刃");
            gailunBuilder.setGroup(HeroProto.Group.blue_group);
    
            // 可以直接使用Builder的链式调用,建造者模式
            HeroProto.LiBai.Builder libaiBuilder = HeroProto.LiBai.newBuilder()
                    .setHeroName("李白")
                    .addAllSkill(Arrays.asList("1", "2", "3"))
                    .setGoods("破军")
                    .setFriend("小乔")
                    .setGroup(HeroProto.Group.red_group);
    
            // 调用build方法构建完整proto对象,这里就可以直接使用
            HeroProto.GaiLun gaiLun = gailunBuilder.build();
            HeroProto.LiBai liBai = libaiBuilder.build();
    
            
            // 如果需要将proto的二进制message对象转换为JSON字符串,使用工具类的方法将proto对象转换为json对象
            String json = JsonFormat.printer().print(gaiLun);
            String json2 = JsonFormat.printer().print(liBai);
            
            System.out.println(json);
            System.out.println(json2);
    		
        }
    }
    
  • 输出

    {
      "heroName": "盖伦",
      "level": 18,
      "skill": ["Q", "W", "E", "R"],
      "goods": "无尽之刃"
    }
    {
      "heroName": "李白",
      "skill": ["1", "2", "3"],
      "goods": "破军",
      "friend": "小乔",
      "group": "red_group"
    }
    

Proto在java中的使用也比较方便,通过建造者模式,可以很方面的赋值和build,生成完整的对象,可以提供操作,例如作为Request或者作为Response等

下一篇会简单介绍Protobuf在Spring中的使用~~