Protobuf是一个灵活、高效、结构化的数据序列化框架,相比于传统的序列化工具,更小、更快、更简单。Protobuf支持数据结构化一次到处使用的特性。
下面我们通过简单的例子来学习如何使用protobuf对POJO对象进行编解码、学习如何与Netty结合使用,及学习两个进程间进行通信和数据交换。
在进行开发 protoc 之前,你需要首先在你的计算机中安装 protoc 编译工具
官网:https://developers.google.com/protocol-buffers?hl=zh-cn
编译器下载路径:
https://github.com/protocolbuffers/protobuf/releases/tag/v3.11.4
在下载程序后,需要将下载 zip 文件中的 bin 目录设置到环境变量中。
路径:控制面板>所有控制面板项>系统>高级系统设置>高级\环境变量>系统变量>path>编辑
然后运行 protoc --version 来确定你的编译运行版本已经被正确配置。
C:\Users\xiayutian>protoc --version
libprotoc 3.11.4
在java中使用protobuf,第一步就是要安装protocal编译器,我们已经安装完成,下面使用它来根据我们配置的.proto文件来自动生成java代码:
$ protoc --java_out=${OUTPUT_DIR} path/to/your/proto/file
如果我们使用maven可以进行如下配置:
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-javaartifactId>
<version>3.11.4version>
dependency>
注意版本好的匹配文件就好
如果我们还想使用protobuf的其他特性,如protobuf JsonFormat功能,我们就添加下面这给配置到pom.xml文件中:
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-java-utilartifactId>
<version>3.11.4version>
dependency>
到此,准备工作已经就绪,下面我们就使用protobuf进行开发吧!
下面我们j就以图书订购例子来讲解,定义BookReq.proto和BookResp.proto,数据文件定义如下:
// [START declaration]
syntax = "proto3";
package netty;
// [END declaration]
// [START java_declaration]
option java_package = "com.moreday.netty_protobuf.codec.protobuf";
option java_outer_classname = "BookReqProto";
// [END java_declaration]
// [START csharp_declaration]
//option csharp_namespace = "Google.Protobuf.Examples.AddressBook";
// [END csharp_declaration]
// [START messages]
message BookReq {
int32 id = 1; // Unique ID number for this bookreq.
string productName = 2;
string userName = 3;
repeated string address = 4;
}
// [START declaration]
syntax = "proto3";
package netty;
// [END declaration]
// [START java_declaration]
option java_package = "com.moreday.netty_protobuf.codec.protobuf";
option java_outer_classname = "BookRespProto";
// [END java_declaration]
// [START csharp_declaration]
//option csharp_namespace = "Google.Protobuf.Examples.AddressBook";
// [END csharp_declaration]
// [START messages]
message BookResp {
int32 subReqID = 1; // Unique ID number for this bookreq.
int32 respCode = 2;
string desc = 3;
}
`生成的java文件copy到工程项目中,如下所示:
简单介绍一下Protobuf的使用:
测试类
package com.moreday.netty_protobuf.codec.serializable.netty;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.InvalidProtocolBufferException;
import com.moreday.netty_protobuf.codec.protobuf.BookReqProto;
/**
* @ClassName TestSubscribeReqProto
* @Description TODO(介绍ProtoBuf编解码使用)
* @author 寻找手艺人
* @Date 2020年4月14日 下午2:39:21
* @version 1.0.0
*/
public class TestBookReqProto {
private static byte[] encode(BookReqProto.BookReq req) {
return req.toByteArray();
}
private static BookReqProto.BookReq decode(byte[] body) throws IOException{
return BookReqProto.BookReq.parseFrom(body);
}
private static BookReqProto.BookReq createBookReq(){
BookReqProto.BookReq.Builder builder = BookReqProto.BookReq.newBuilder();
builder.setId(1);
builder.setProductName("Head First设计模式");
builder.setUserName("寻找手艺人");
List<String> address = new ArrayList<String>();
address.add("98.00桐梓");
address.add("198.00遵义");
address.add("298.00济宁");
address.add("398.00青岛");
builder.addAllAddress(address);
return builder.build();
}
public static void main(String[] args) throws IOException {
BookReqProto.BookReq req = createBookReq();
System.out.println("Before encode: "+req.toString());
BookReqProto.BookReq req2 = decode(encode(req));
System.out.println("After decode:"+req2.toString());
//编解码前后比较
System.out.println("Assert equal-->"+req.equals(req2));
}
}