Java中使用protobuf

一、简介

Protocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化、反序列化。

Protocol Buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。

Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。

你可以定义数据的结构,然后使用特殊生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序
与JSON相比

protobuf的效率高,不过protobuf生成的是字节码,可读性相比之略差

Protobuf不仅仅是一种消息格式,它还是一组用于定义和交换这些消息的规则和工具。 谷歌是这个协议的创造者,已开源,并为常用的编程语言提供生成代码的工具,

如JavaScript,Java,PHP,C#,Ruby,Objective C,Python,C ++和Go。 除此之外,Protobuf具有比JSON更多的数据类型,如枚举和方法,并且还大量用于RPC(远程过程调用)

参考资料

名称 地址
protobuf 编译器 Releases · protocolbuffers/protobuf · GitHub
Protobuf 语法指南 [译]Protobuf 语法指南

二、protobuf 环境配置

1.下载编译器

选择自己需要的版本下载即可,我这里下载的是win64 3.15.3,下载之后进行解压

2.配置环境变量

path 系统变量中增加配置,也就是你的解压文件位置

3.检查是否配置成功

cmd 之后,输入

|----------------|
| protoc |

查看版本

|--------------------------|
| protoc --version |

这样我们就可以在命令行去生成 proto 文件了

二、idea 中使用 protobuf

1.idea 安装 protobuf 相关插件

任意安装以下插件即可,安装之后重启 idea

一个是根据 .proto 文件来生成 proto 对象

一个是使得 idea 支持我们的 proto 语法,例如关键词高亮等功能

2.写一个简单的 proto

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| //使用 proto3 语法 ,未指定则使用proto2 syntax = "proto3"; //生成 proto 文件所在包路径 package com.wxw.notes.protobuf.proto; //生成 proto 文件所在包路径 option java_package = "com.wxw.notes.protobuf.proto"; //生成 proto 文件名 option java_outer_classname="DemoProto"; message Demo{ //自身属性 int32 id = 1; string code = 2; string name = 3; } |

如果发现有这种红色标识,千万不要以为是我们 Java 里面的异常错误,这只是 proto 的语法高亮

3.生成 proto 对象

选中我们新建的.proto 文件,右键,选择框中的选项就可以生成了

生成后的 proto 文件如下

三、protobuf方法使用

1.序列化和反序列化

复制代码

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| package com.wxw.notes.protobuf.test; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.MessageOrBuilder; import com.google.protobuf.TextFormat; import com.google.protobuf.util.JsonFormat; import com.wxw.notes.protobuf.proto.DemoProto; import java.util.Arrays; public class SimpleTestMain { public static void main(String[] args) { //初始化数据 DemoProto.Demo.Builder demo = DemoProto.Demo.newBuilder(); demo.setId(1) .setCode("001") .setName("张三") .build(); //序列化 DemoProto.Demo build = demo.build(); //转换成字节数组 byte[] s = build.toByteArray(); System.out.println("protobuf数据bytes[]:" + Arrays.toString(s)); System.out.println("protobuf序列化大小: " + s.length); DemoProto.Demo demo1 = null; String jsonObject = null; try { //反序列化 demo1 = DemoProto.Demo.parseFrom(s); //转 json jsonObject = JsonFormat.printer().print(demo1); } catch (InvalidProtocolBufferException e) { e.printStackTrace(); } System.out.println("Json格式化结果:\n" + jsonObject); System.out.println("Json格式化数据大小: " + jsonObject.getBytes().length); } |

2.protobuf 和 JSON 互相转换

引入依赖

|----------------------------------------------------|
| com.google.protobufprotobuf-java-util3.7.1 |

代码实现

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public class ProtoJsonUtils { public static String toJson(Message sourceMessage) throws IOException { String json = JsonFormat.printer().print(sourceMessage); return json; } public static Message toProtoBean(Message.Builder targetBuilder, String json) throws IOException { JsonFormat.parser().merge(json, targetBuilder); return targetBuilder.build(); } } |

对于一般的数据类型,如int,double,float,long,string都能够按照理想的方式进行转化。对于protobuf中的enum类型字段,会被按照enum的名称转化为string。对于bytes类型的字段,则会转化为utf8类型的字符串

3.protobuf 与 Java 对象互转

引入依赖

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <!-- protocol buffer support --> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>${protobuf.version}</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-all</artifactId> <version>${grpc.version}</version> </dependency> |

代码实现

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public class ProtobufBeanUtil { private ProtobufBeanUtil(){ } /** * 将ProtoBean对象转化为POJO对象 * * @param destPojoClass 目标POJO对象的类类型 * @param sourceMessage 含有数据的ProtoBean对象实例 * @param <PojoType> 目标POJO对象的类类型范型 * @return * @throws IOException */ public static <PojoType> PojoType toPojoBean(@NotNull Class<PojoType> destPojoClass, @NotNull Message sourceMessage) throws IOException { String json = JsonFormat.printer().print(sourceMessage); return new Gson().fromJson(json, destPojoClass); } /** * 将POJO对象转化为ProtoBean对象 * * @param destBuilder 目标Message对象的Builder类 * @param sourcePojoBean 含有数据的POJO对象 * @return * @throws IOException */ public static void toProtoBean(@NotNull Message.Builder destBuilder, @NotNull Object sourcePojoBean) throws IOException { String json = new Gson().toJson(sourcePojoBean); JsonFormat.parser().merge(json, destBuilder); } |

相关推荐
wjs20242 小时前
状态模式(State Pattern)
开发语言
我命由我123452 小时前
Kotlin 数据容器 - List(List 概述、创建 List、List 核心特性、List 元素访问、List 遍历)
java·开发语言·jvm·windows·java-ee·kotlin·list
liulilittle2 小时前
C++ TAP(基于任务的异步编程模式)
服务器·开发语言·网络·c++·分布式·任务·tap
励志要当大牛的小白菜3 小时前
ART配对软件使用
开发语言·c++·qt·算法
武子康4 小时前
Java-80 深入浅出 RPC Dubbo 动态服务降级:从雪崩防护到配置中心秒级生效
java·分布式·后端·spring·微服务·rpc·dubbo
爱装代码的小瓶子5 小时前
数据结构之队列(C语言)
c语言·开发语言·数据结构
YuTaoShao6 小时前
【LeetCode 热题 100】131. 分割回文串——回溯
java·算法·leetcode·深度优先
源码_V_saaskw7 小时前
JAVA图文短视频交友+自营商城系统源码支持小程序+Android+IOS+H5
java·微信小程序·小程序·uni-app·音视频·交友
Maybe_ch7 小时前
.NET-键控服务依赖注入
开发语言·c#·.net
超浪的晨7 小时前
Java UDP 通信详解:从基础到实战,彻底掌握无连接网络编程
java·开发语言·后端·学习·个人开发