Protocol ——Buffer(大傻蛋子版)

Protobuf解决的问题:
现有的数据交换格式(XML)的解析性能差
需要编写大量的代码来解析数据
数据兼容性问题

下载protobuf Compiler

下载链接.

下载proto插件(打勾的)

在这里插入图片描述

创建Maven项目导入依赖

<!-- 1 -->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.5.1</version>
        </dependency>
<!-- 2 -->
        <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java-util -->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <version>3.5.1</version>
        </dependency>
<!-- 3 -->
        <!-- https://mvnrepository.com/artifact/io.grpc/grpc-all -->
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
            <version>1.11.0</version>
        </dependency>
        <!--protobuf相关end-->
    </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.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.0</version>
                <configuration>
                    <protocArtifact>
                        com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}
                    </protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>
                        io.grpc:protoc-gen-grpc-java:1.11.0:exe:${os.detected.classifier}
                    </pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            
        </plugins>
    </build>

创建proto文件

在这里插入图片描述

Kari.proto中写入代码:

syntax = "proto2";//指定了用的是proto2版本语法,不写默认proto2语法 
package com.kari;//定义proto的包名,可以通过package防止命名冲突。(也是生成Java类的地址)
option java_outer_classname = "Kari";//生成的Java类的名称
message Person {

  optional int32 id=1;
  required string name=2;
  message P{
    optional int32 old=1;
    optional string ip=2;
    repeated int32 imp=3;
  }
  repeated P p=3;
  //枚举类
  enum Sex {
    MAN = 0;
    WOMAN = 1;
  }
 optional Sex sex = 4 ;
}

proto文件生成Java类

proto生成Java类的方法有很多,这里我选择了一个看起来不是很聪明的方法
在这里插入图片描述

编写测试类测试:

 public String Testprotobuf() {
        //获取person对象
        //这里的person对象构造器被私有化,我们通过person的内部类Builder来构建builder
        Kari.Person.Builder kari = Kari.Person.newBuilder();
        //通过person的内部类builder提供了构建Student相关属性的set方法
        kari.setId(10);
        kari.setName("刘四");
        kari.setSex(Kari.Person.Sex.MAN);//枚举
        setbidP(kari);

        //序列化
        Kari.Person person =kari.build();
         /*
        反序列化(String类型反序列化放到proto生成的Java类中)
         */
        String data ="CAoSBuWImOWbmxoNCAoSA29qbxgKGAEYAiAA";
        System.out.println(Base64.getEncoder().encodeToString(kari.build().toByteArray()));
        byte[] decode = null;
        try {
            //使用base64解码读取到的字符串,
            decode = Base64.getDecoder().decode(data);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Kari.Person pp=null;
        try {
            // 将解析出来的字符串进行反序列化
            pp = Kari.Person.parseFrom(decode);
        } catch (Exception e) {
            // 如果解析失败,就返回一个特殊的实例
            pp = Kari.Person.newBuilder().setName("-1").setId(-1).build();
            e.printStackTrace();
        }
        System.out.println(pp.toString());
      
        System.out.println("protobuf数据大小: " + person.toByteString().size());
        //再将封装有数据的对象实例,转换为字节数组,用于数据传输、存储等
        byte[] stuByte = person.toByteArray();
        //这里得到了字节数组后,我们可以将该数据进行数据传输或存储,这里至于用什么技术传输就根据具体情况而定
        //假如这里通过传输,下面的代码接到了该数据
        //接收方 ,这里为了方便我们就写在一个类里面
        //将字节数据反序列化为对应的对象实例
        Kari.Person person1 = null;
        try {
            person1 = Kari.Person.parseFrom(stuByte);
            //这里得到了Student实例了,就可以根据需要来操作里面的数据了
            System.out.println("实例模式:"+"\n"+person1.getP(0)+""+person1.getId()+""+person1.getName()+"_");
            System.out.println((person1.getSex().getNumber()==0?"男":"女"));
            System.out.println("____________________________________________-");
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        /*如何快速的进行json格式化*/
        String jsonObject = "";
        try {
            jsonObject = JsonFormat.printer().print(person1);
        } catch (InvalidProtocolBufferException e) {
            e.getMessage();
        }
        System.out.println("Json格式:"+"\n"+jsonObject.toString());
        System.out.println("json数据大小: " + jsonObject.getBytes().length);
        System.out.println("____________________________________________-");
        System.out.println("protobuf序列化格式:"+"\n"+kari.toString());
        System.out.println("数据大小: " +kari.toString().getBytes().length);
        System.out.println("_____________________________________-"+"\n");
        try {
           // System.out.println(kari.TextFormat.printToUnicodeString);
            String decp = new String(kari.toString().getBytes(),"utf-8");
             String decp = new String(kari.toString().getBytes(),"utf-8");
            System.out.println(decp);//输出的中文为八进制
            System.out.println(kari.getNameBytes().toStringUtf8());//输出为中文
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return kari.toString();
    }
    public  void setbidP(Kari.Person.Builder k) {
        //获取P对象
        Kari.Person.P.Builder p = Kari.Person.P.newBuilder();
        //获取array类型
        /**
         * 如果对象类型是array那不妨创建两个对象
         */
        List<Integer> list = new ArrayList<Integer>();
        list.add(1);list.add(2);
        p.addImp(10);
        p.addAllImp(list);
        p.setIp("ojo").setOld(10);
        k.addP(p);
    }
}

执行结果示例

protobuf数据大小: 27
实例模式:
old: 10
ip: "ojo"
imp: 10
imp: 1
imp: 2
10刘四_
男
____________________________________________-
Json格式:
{
  "id": 10,
  "name": "刘四",
  "p": [{
    "old": 10,
    "ip": "ojo",
    "imp": [10, 1, 2]
  }],
  "sex": "MAN"
}
json数据大小: 120
____________________________________________-
protobuf序列化格式:
id: 10
name: "\345\210\230\345\233\233"
p {
  old: 10
  ip: "ojo"
  imp: 10
  imp: 1
  imp: 2
}
sex: MAN

数据大小: 105
_____________________________________-

id: 10
name: "\345\210\230\345\233\233"
p {
  old: 10
  ip: "ojo"
  imp: 10
  imp: 1
  imp: 2
}
sex: MAN
刘四

详细原文:

bui.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值