官方:Protocol buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。
Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。
你可以定义数据的结构,然后使用特殊生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。
Protocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化、反序列化,常用于RPC 系统(Remote Procedure Call Protocol System)和持续数据存储系统。
其类似于XML生成和解析,但protobuf的效率高于XML,不过protobuf生成的是字节码,可读性比XML差,类似的还有json、Java的Serializable等。
很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
首先要下载编译器 编译器下载https://github.com/protocolbuffers/protobuf/releases
且需要设置环境变量。如下图,按需下载即可,我这里下载的是protoc-3.10.0-rc-1-win64.zip
下载后,将protoc.exe的路径配置到环境变量Path中,如下图:
然后再cmd中运行 protoc 出现如下画面,则表示配置成功:
也可以通过查看版本判端是否成功:
这样我们就可以用命令编译 .proto 文件了,命令如下:
protoc --java_out=D:/test/ person.proto
我们通常都用IDE进行开发,老在命令行编译,很不方便,所以要在idea里使用。
注意:这里用的springboot方式。
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-javaartifactId>
<version>3.9.1version>
dependency>
<plugin>
<groupId>org.xolstice.maven.pluginsgroupId>
<artifactId>protobuf-maven-pluginartifactId>
<version>0.6.1version>
<configuration>
<protocExecutable>D:/DevTools/protoc-3.10.0-rc-1-win64/bin/protoc.exeprotocExecutable>
configuration>
plugin>
在src/main下新建proto包,在proto下新建person.proto文件,文件内容如下:
syntax = "proto3";
option java_package = "com.lhyt.entity";
option java_outer_classname = "PersonEntity";
message Person {
int32 id = 1;
string name = 2;
string email = 3;
}
注意:关于proto文件的编写语法规则,如果有时间会有一篇文章专门介绍。
目录结构如下:
"D:\Program Files\Java\jdk1.8.0_161\bin\java.exe" -Dmaven.multiModuleProjectDirectory=E:\2019code\demo -Dmaven.home=D:\DevTools\apache-maven-3.3.9 -Dclassworlds.conf=D:\DevTools\apache-maven-3.3.9\bin\m2.conf "-javaagent:D:\DevTools\IntelliJ IDEA 2019.1.1\lib\idea_rt.jar=64510:D:\DevTools\IntelliJ IDEA 2019.1.1\bin" -Dfile.encoding=UTF-8 -classpath D:\DevTools\apache-maven-3.3.9\boot\plexus-classworlds-2.5.2.jar org.codehaus.classworlds.Launcher -Didea.version2019.1.1 org.xolstice.maven.plugins:protobuf-maven-plugin:0.6.1:compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building demo 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- protobuf-maven-plugin:0.6.1:compile (default-cli) @ demo ---
[INFO] Compiling 1 proto file(s) to E:\2019code\demo\target\generated-sources\protobuf\java
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.369 s
[INFO] Finished at: 2019-09-19T17:02:25+08:00
[INFO] Final Memory: 21M/309M
[INFO] ------------------------------------------------------------------------
执行完成后,会在target/generated-sources/protobuf/下生成对应文件,如下图:
新建测试类ProtobufTest.java,如下:
package com.lhyt.test;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import com.lhyt.entity.PersonEntity;
/**
* 测试protobuf
*
* @author wangdy
* @date 2019/9/19 17:14
*/
public class ProtobufTest {
public static void main(String[] args) throws InvalidProtocolBufferException {
//通过PersonEntity的内部类Builder来构建builder
PersonEntity.Person.Builder personBuilder = PersonEntity.Person.newBuilder();
//通过PersonEntity的内部类builder提供了构建Person相关属性的set方法
personBuilder.setId(1);
personBuilder.setName("张三");
personBuilder.setEmail("[email protected]");
//序列化
PersonEntity.Person personEntity = personBuilder.build();
System.out.println("protobuf数据bytes[]:" + Arrays.toString(personEntity.toByteArray()));
System.out.println("protobuf数据大小: " + personEntity.toByteString().size());
//再将封装有数据的对象实例,转换为字节数组,用于数据传输、存储等
byte[] bytes = personEntity.toByteArray();
/**
* 这里得到了bytes字节数组后,我们可以将该数据进行数据传输或存储,这里至于用什么技术传输就根据具体情况而定
* 通常我们进行rpc通信传输数据类型会用protobuf
* 假如这里bytes通过传输,另一个项目获取到改bytes数据后进行反序列化操作
*
*/
//将字节数据反序列化为对应的对象实例
PersonEntity.Person person = null;
try {
person = PersonEntity.Person.parseFrom(bytes);
//这里得到了Person实例了,可以根据需要来操作里面的数据了
System.out.println("学生ID:" + person.getId());
System.out.println("姓名:" + person.getName());
System.out.println("邮箱:" + person.getEmail());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
/*进行json格式化*/
String jsonObject = JsonFormat.printer().print(person);// 此处有异常需要处理
System.out.println("格式化结果:\n" + jsonObject);
System.out.println("Json格式化数据大小: " + jsonObject.getBytes().length);
}
}
运行结果如下:
protobuf数据bytes[]:[8, 1, 18, 6, -27, -68, -96, -28, -72, -119, 26, 13, 49, 50, 51, 52, 53, 54, 64, 113, 113, 46, 99, 111, 109]
protobuf数据大小: 25
学生ID:1
姓名:张三
邮箱:[email protected]
格式化结果:
{
"id": 1,
"name": "张三",
"email": "[email protected]"
}
Json格式化数据大小: 61
ok,这就是Maven工程中使用Protobuf的完整示例了。