您现在的位置:首页 > >

Protocol Buffer的使用

发布时间:

大家对于json xml这两个数据传输协议都比较熟悉,但是说起谷歌的protocol buffer,可能大家很多人没有接触过。在此之前,先介绍下数据传输协议中经常会听到的两个名词。


序列化:将数据结构或对象转化为二进制字符串的过程。反序列化:将二进制字符串转化为数据结构或对象的过程。


xml是用标签来存储数据,json使用独立于编程语言的文本存储和表示数据,而protocol buffer是使用通过序列化来完成数据的传输。从这一点上看,protocol buffer相比于前两者更小、更快,更符合数据传输量大的场景,使用和维护起来也很简单。下面介绍protobuf在java下的使用方法。


一、protocol buffer编译器安装

protocol buffer提供了数据结构和对象的语法定义,其源文件为.proto后缀,通过编译器可以自动生成相应语言的序列化对象工具。


github下载地址:https://github.com/google/protobuf


如果是windows环境,还需要下载protoc.exe,并复制到protobuf目录下的src文件夹下。下载地址:https://download.csdn.net/download/antgan/9593735


编辑系统环境变量PATH,将protoc.exe的存放目录(即protobuf下的src)添加到PATH中。


二、使用IDEA新建maven项目

pom.xml引入的依赖如下



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">
4.0.0

com.neymar
protobuf-test
1.0-SNAPSHOT



com.google.protobuf
protobuf-java
3.4.0




整个项目的目录如下




proto存放.proto文件,main调用protobuf编译器,java存放生成的java文件


三、编辑proto文件

protobuf的语法跟java定义类的语法很相似,下一节将会详细介绍,大家可以先看一个实例


option java_outer_classname = "StudentEntity";
message Student {
required int32 id = 1;
required string name = 2;
optional string nickname = 3;
}

java_outer_classname是输出的java文件名,message定义了一个数据结构,required和optional都是修饰符,前者指该字段是必须有且一个,后者指有0个或1个,等号后边的数字是对字段进行编号。


四、编译proto文件

编译可以通过java main方法来执行cmd命令,或者直接在cmd输入相应的命令


cmd中的命令为protoc.exe -I=源地址 --java_out=输出地址 源地址/xxx.proto


package com.neymar.prototest;

import java.io.IOException;

public class main {
public static void main(String[] args) {
String protoFile = "student-entity.proto";//
String strCmd = "C:/Program Files/protobuf-master/src/protoc.exe -I=./src/main/java/com/neymar/prototest/proto --java_out=./src/main/java/com/neymar/prototest/java ./src/main/java/com/neymar/prototest/proto/"+ protoFile;
try {
Runtime.getRuntime().exec(strCmd);
} catch (IOException e) {
e.printStackTrace();
}
}
}

五、序列化及反序列化

package com.neymar.prototest;

import com.google.protobuf.InvalidProtocolBufferException;
import com.neymar.prototest.java.StudentEntity;

public class main {
public static void main(String[] args) throws InvalidProtocolBufferException {
StudentEntity.Student.Builder builder= StudentEntity.Student.newBuilder();
builder.setId(1);
builder.setName("neymar");
builder.setNickname("ney");
StudentEntity.Student student = builder.build();
System.out.println("序列化前 :"+ student.toString());

System.out.println("===========序列化后的字符==========");
for(byte b : student.toByteArray()){
System.out.print(b);
}
System.out.println();
System.out.println("================================");
System.out.println();

//Byte[]就是序列化后的字符串,反序列化成Student类
byte[] byteArray =student.toByteArray();
StudentEntity.Student stu = StudentEntity.Student.parseFrom(byteArray);
System.out.println("反序列化后:" +stu.toString());
}
}

输出截图




六、对比总结

相对于上面的例子,如果我们把相同的对象使用json来进行传输,其内容为{"id":1,"name":"neymar","nickname":"ney"}。我们可以总结下protobuf相比于json的优势:



    使用二进制来存储对象数据,体积小,序列化速度快,传输速度快使用简单,多*台只用管理维护同一套proto文件,可以跨*台跨语言使用protobuf使用非明文传输,数据安全上优于jsonprotobuf对于数据结构的定义可以兼容更多的数据类型,例如数据结构的嵌套使用、枚举等(protobuf的具体语法规则在将在另一篇博客中进行介绍)RPC的数据传输适合使用protobuf

但在下面的情况中,使用json会比protobuf更好:



    protobuf由于是二进制传输,可读性相比于json,是远远比不上的服务器与WEB浏览器的通信使用json比使用protocol要好得多


热文推荐
猜你喜欢
友情链接: