我们日常写代码,服务之间的接口交互基本使用的都是JSON格式的数据,其可读性及易用性都较好,对于其它格式的协议研究过少,最近经手的项目涉及到与其它公司进行数据汇总,数据的访问频率非常高且数据量较大,除引入Kafka等消息中间件外,另计划将通信协议格式调整为谷歌的ProtoBuf协议。
小豪近期也简要研究了一下ProtoBuf,本文将从ProtoBuf的概念开始介绍,逐步带大家搞清楚如何使用Java操作ProtoBuf协议,旨在帮助大家快速上手Protobuf的基本使用。本文大纲如下:
1、何为ProtoBuf
百度百科对它的介绍的是:Protocol Buffers(简称ProtoBuf)是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。它不依赖于语言和平台并且可扩展性极强。现阶段官方支持C++、JAVA、Python、Objective C、C#、Ruby、PHP、JavaScript八种编程语言,还可以找到大量的几乎涵盖所有语言的第三方拓展包。
Protocol Buffers在谷歌被广泛用于各种结构化信息存储和交换。Protocol Buffers作为一个自定义的远程过程调用(RPC)系统,用于在谷歌几乎所有的设备间的通信。
简要理解,ProtoBuf即谷歌自己制定的一种数据格式,类似于Json、XML等
1.1 优劣性
谷歌制定的ProtoBuf最大的优势就是高效性,不同于Json和XML使用文本进行数据编码,ProtoBuf采用二进制进行编码,其传输速度、解析速度都比较快,序列化后的体积也更小。
但相较于Json和XML,其可读性太差了,只能通过反序列化得到可读的数据内容,另外通用性也较差,只在谷歌内部用的比较多。
2、ProtoBuf文件语法
这里我们首先编写一个简要的ProtoBuf文件,内容如下,文件名为,文件内容如下:
2.1 基本结构
ProtoBuf语法结构如下:
- 语法版本:首行代表当前使用的是规范的语法
- 包名:第二、三行代表输出Java文件之后的对应的包以及类名(注:生成的Java类名不要与声明的消息名称一致)
- 消息定义:剩下的其它行代表消息结构与枚举类型。
其中关键字,作用为定义一种消息类型,类似于Java中定义实体类一样,里面定义所包含的属性,属性由字段规则、字段类型、字段名称和字段编号组成。
2.2 字段规则
字段规则类似于MySQL中的约束,即对数据的限制条件。
ProtoBuf常见的约束有以下几种:
- singular:字段可以出现次或出现次(不得超过次),语法默认的字段规则
- repeated:字段可以出现任意多次(包括次),类似于Java中的集合
2.3 字段类型
字段类型包括常用的标量类型与复合类型。
2.3.1 标量类型
标量类型类似于Java中的基本类型,对应关系如下表所示:
2.3.2 复合类型
复合类型可以是其它消息,或枚举等,类似于Java中的引用类型。
这里分别列举一下Java中、等数据结构在ProtoBuf中的用法:
① 引用其它消息、枚举:
②引用集合:
③引用集合:
2.4 字段编号
字段编号即字段的唯一标识,从开始编号,后续ProtoBuf传递时,实际上传递是就是该编号而非字段名
1、生成proto对应Java文件
1.1 下载编译器
首先我们需要下载ProtoBuf编译器,小豪这里下载的是21.10版本win64位的(github下载地址在这)
下载后直接解压即可。
1.2 编写proto文件
之后编写好对应的proto文件,这里我们直接使用下面的proto文件:
将proto文件放置于下载的ProtoBuf编译器的目录下:
1.3 输出Java文件
执行命令
如图,会在我们配置的输出包名路径下,生成对应的Java文件:
拷贝到我们项目中即可。
另外,IDEA也内置ProtoBuf相关插件,可通过插件生成对应的Java文件,但配置过程较为繁琐
2、引入第三方依赖库
操作ProtoBuf,我们需要在中引入两个包:
这里对应的版本必须要与下载的ProtoBuf编译器版本保持一直,否则会报错。
如刚才我们下载的编译器版本为protoc-21.10,使用proto3语法,这里对应的包版本即为3.21.10版本
3、编写测试类
3.1 序列化
序列化一般分为4步:
①创建对象构造器,使用方法:
②为对象属性赋值,使用方法:
③构造对象,使用对象构造器的方法:
④序列化Java对象,使用对象的方法:
3.2 反序列化
序列化一般分为2步:
①反序列为Java对象,使用方法:
②获取对象属性值,使用方法:
3.3 完整测试结果
控制台输出:
本文从ProtoBuf的基础概念介绍开始,最后引申到Java操作ProtoBuf协议,其最大的特点就是体积小、传输高效,一方面由于其使用二进制方式存储,另一方面其采用TLV(Tag-Length-Value)数据编码格式,进一步压缩了字节占用,从而减小了传输开销。
本文内容作为随笔,也希望能帮助到初学者,如果大家觉得内容对你有帮助,不妨考虑点点赞,关注关注小豪,后续小豪将会继续更新其它Java相关文章~
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/12469.html