Protocol Buffers介绍
- Protocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化、反序列化,常用于RPC 系统和持续数据存储系统。
- 其类似于XML生成和解析,但protobuf的效率高于XML,不过protobuf生成的是字节码,可读性比XML差,类似的还有json、Java的Serializable等。
- 很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据
Idea 安装protobuf插件
安装插件protobuf Support,之后重启
- protobuf-jetbrains-plugin-0.13.0.zip,在IDEA中安装插件即可
使用ProtoBuf序列化数据
配置Maven依赖与插件
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<!-- Protobuf插件 -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
<protocArtifact>
com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}
</protocArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
编写 proto 文件
在main文件夹下,创建 proto 目录,并编写proto文件 file名user.proto
syntax = "proto3";
option java_package = "com.donglin.protobuf";
option java_outer_classname = "DemoModel";
message User {
int32 id = 1;
string name = 2;
string sex = 3;
}
注意:classname不能与message name一样
protobuf与java类型对照表
proto Type | Java Type | 备注 |
---|---|---|
double | double | |
float | float | |
int32 | int | 使用可变长度编码。负数编码效率低下–如果您的字段可能具有负值,请改用sint32。 |
int64 | long | 使用可变长度编码。负数编码效率低下–如果您的字段可能具有负值,请改用sint64。 |
uint32 | int | 使用可变长度编码。 |
uint64 | long | 使用可变长度编码。 |
sint32 | int | 使用可变长度编码。有符号的int值。与常规int32相比,它们更有效地编码负数。 |
sint64 | long | 使用可变长度编码。有符号的int值。与常规int64相比,它们更有效地编码负数。 |
fixed32 | int | 始终为四个字节。如果值通常大于2^28,则比uint32更有效。 |
fixed64 | long | 始终为四个字节。如果值通常大于2^28,则比uint64更有效。 |
sfixed32 | int | 始终为四个字节。 |
sfixed64 | long | 始终为八个字节。 |
bool | boolean | |
string | string | 字符串必须始终包含UTF-8编码或7位ASCII文本。 |
bytes | ByteString | 可以包含任意字节序列。 |
执行protobuf:compile编译命令
编写代码使用ProtoBuf序列化、反序列化
import com.donglin.protobuf.DemoModel;
import com.google.protobuf.InvalidProtocolBufferException;
/**
* protobuf的使用方式
* 使用protobuf进行数据的序列化和反序列化
*/
public class ProtobufDemo {
public static void main(String[] args) throws InvalidProtocolBufferException {
//实例化protobuf
DemoModel.User.Builder builder = DemoModel.User.newBuilder();
//给user进行赋值
builder.setId(1); //用户id
builder.setName("张三"); //用户名
builder.setSex("男"); //用户性别
//获取user对象的属性
DemoModel.User userBuilder = builder.build();
System.out.println(userBuilder.getId());
System.out.println(userBuilder.getName());
System.out.println(userBuilder.getSex());
/**
* 数据的序列化和反序列化
* 序列化:意味着可以将对象转换成字节码数据存储到kafka中
* 反序列化:意味着可以将kafka中的数据消费出来以后,反序列化成对象使用
*/
//每一个对象序列化换成二进制的字节码存储到kafka
byte[] bytes = builder.build().toByteArray();
for (byte aByte : bytes) {
System.out.println(aByte);
}
//从kafka中消费出来的序列化数据,可以反序列化成对象使用
DemoModel.User user = DemoModel.User.parseFrom(bytes);
System.out.println(user.getId());
System.out.println(user.getName());
System.out.println(user.getSex());
}
}