【保姆级】Protobuf详解及入门指南

目录

Protobuf概述

什么是Protobuf

为什么要使用Protobuf

Protobuf实战

环境配置

创建文件

解析/封装数据

附录

AQin.proto 完整代码


Protobuf概述

什么是Protobuf

Protobuf(Protocol Buffers)协议😉 Protobuf 是一种由 Google 开发的二进制序列化格式和相关的技术,它用于高效地序列化和反序列化结构化数据,通常用于网络通信、数据存储等场景

为什么要使用Protobuf

其实 Protobuf 在许多领域都得到了广泛应用,特别是在分布式系统、RPC(Remote Procedure Call)框架和数据存储中,它提供了一种高效、简洁和可扩展的方式来序列化和交换数据,Protobuf 的主要优点包括:

  1. 高效性:Protobuf 序列化后的二进制数据通常比其他序列化格式(比如超级常用的JSON)更小,并且序列化和反序列化的速度更快,这对于性能敏感的应用非常有益。
  2. 简洁性:Protobuf 使用一种定义消息格式的语法,它允许定义字段类型、顺序和规则(消息结构更加清晰和简洁)
  3. 版本兼容性:Protobuf 支持向前和向后兼容的版本控制,使得在消息格式发生变化时可以更容易地处理不同版本的通信。
  4. 语言无关性:Protobuf 定义的消息格式可以在多种编程语言中使用,这有助于跨语言的通信和数据交换(截至本文发布目前官方支持的有C++/C#/Dart/Go/Java/Kotlin/python)
  5. 自动生成代码:Protobuf 通常与相应的工具一起使用,可以自动生成代码,包括序列化/反序列化代码和相关的类(减少了手动编写代码的工作量,提高效率,后面的🌰里有保姆级操作指南)

Protobuf实战

环境配置

首先我们需要在 pom.xml 文件中添加如下依赖:

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.20.3</version>
</dependency>

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java-util</artifactId>
    <version>3.20.3</version>
</dependency>

接着如果你希望.proto文件可以被idea识别的话,就需要安装 Protobuf 插件(非必要)

创建文件

然后我们创建一个.proto文件,如下图(完整代码在文末附录)

其中 syntax = "proto3" 表示协议版本,option java_package = "com.aqin.protobuf" 表示生成的类所处的层级,option java_multiple_files = true 表示需要將生成的类拆分为多个(false 的话就是不需要),MyRequest 和 Header 是消息结构。

进入到文件📃AQin.proto所在目录下,执行如下代码:

protoc -I=./ --java_out=./ ./AQin.proto

参数说明:

  • -I 用于指定 .proto 文件所在的路径(也可以用-proto_path代替)
  • --java_out 用于指定生成的 java 文件的路径
  • ./AQin.proto 就是需要编译的.proto文件

有一点需要注意的是这三个路径要使用相对路径就都使用相对路径,要使用绝对路径就都使用绝对路径(不要混着用),执行完成后,就会在指定的位置生成指定的文件,如下图

然后我们就可以通过生成的Java类来对接收到的信息进行解析,或者封装数据进对象进行发送

解析/封装数据

常用API

  • newBuilder():用于创建Java类(通过.proto文件生成的)并返回该对象
    • setXXX():设置属性值
    • getXXX():获取属性值
  • byte[] toByteArray():用于序列化信息并返回一个字节数组
  • writeTo(OutputStream output): 序列化信息并写入一个输出流
  • parseFrom(byte[] data):解析传入的字节数组(一般用于接收数据)
  • parseFrom(InputStream input):解析传入的输入流(一般用于接收数据)

那我们上面的AQin.proto举个🌰

MyInfo myInfo = MyInfo.newBuilder().setName("Zhangsan");
Body body = Body.newBuilder().setMyInfo(myInfo).build();
ByteBuffer byteBuffer = ByteBuffer.allocate(body.toByteArray().length);
body.writeTo(CodedOutputStream.newInstance(byteBuffer));
//然后就可以发送了~~

附录

AQin.proto 完整代码

//协议版本
syntax = "proto3";
//生成的类所处的层级
option java_package = "com.aqin.protobuf";

//是否需要將生成的类拆分为多个
option java_multiple_files = true;

// request
message MyRequest{
  Header header = 1;
  Body body = 2;
}

//Header
message Header {
  uint32  RequestId = 1;
  int64   Timestamp = 2;
}

//Body
message Body {
  MyInfo Info = 1;  //消息
  ServiceResult serviceResult = 2;  //结果反馈
}

message MyInfo{
  string  name = 1;
  string  age = 2;
}

message ServiceResult{
  uint32 ErrorCode = 1;
  string ErrorMsg = 2;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/448096.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mysql8的优化(DBA)

Mysql8的优化 1、Mysql的安装优化1.1 修改配置参数&#xff08;命令行、配件文件&#xff09;1.1.1 命令行修改配置参数1.1.2 参数持久化1.1.3 Mysql多实例启动&#xff0c;以及配置密码文件 1.2 查询表的相关参数&#xff0c;以及表空间管理 2、Mysql高级优化&#xff08;SQL&…

编译支持国密的抓包工具 WireShark

目录 前言WireShark支持国密的 WireShark小结前言 在上一篇文章支持国密的 Web 服务器中,我们搭建了支持国密的 Web 服务器,但是,我们使用 360 安全浏览器去访问,却出现了错误: 是我们的 Web 服务器没有配置好?在这里插入图片描述还是 360 安全浏览器不支持国密?还是两…

SSL证书:构建网络安全的基石

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Linux学习——线程的控制

目录 ​编辑 一&#xff0c;线程的创建 二&#xff0c;线程的退出 1&#xff0c;在子线程内return 2,使用pthread_exit(void*) 三&#xff0c;线程等待 四&#xff0c;线程获取自己的id值 五&#xff0c;线程取消 六&#xff0c;线程分离 一&#xff0c;线程的创建 在对…

全面的 DevSecOps 指南:有效保护 CI/CD 管道的关键注意事项

数字化转型时代带来了对更快、更高效、更安全的软件开发流程的需求。DevSecOps&#xff1a;一种将安全实践集成到 DevOps 流程中的理念&#xff0c;旨在将安全性嵌入到开发生命周期的每个阶段 - 从代码编写到生产中的应用程序部署。DevSecOps 的结合可以带来许多好处&#xff0…

抖音视频提取gif怎么做?分分钟帮你生成gif

通过将视频转换成gif动图的方式能够方便的在各种平台上分享、传播。相较于视频文件&#xff0c;gif动图的体积更小&#xff0c;传播起来更方便&#xff0c;能够吸引大众的注意力。下面&#xff0c;就来给大家分享一个gif图片制作&#xff08;https://www.gif.cn/&#xff09;的…

mybatisplus的条件构造器

条件构造器wrapper&#xff0c;主要用于构造sql语句的where条件&#xff0c;他更擅长这个&#xff0c;但也可以用于构造其他类型的条件&#xff0c;比如order by、group by等。 条件构造器的使用经验&#xff1a; 基于QueryWrapper的查询 练习1. void testQueryWrapper(){Q…

服务器集群 -- nginx配置tcp负载均衡

当面临高流量、高可用性、水平扩展、会话保持或跨地域流量分发等需求时&#xff0c;单台服务器受限于硬件资源、性能有限不能满足应用场景的并发需求量时&#xff0c;引入负载均衡器部署多个服务器共同处理客户端的并发请求&#xff0c;可以帮助优化系统架构&#xff0c;提高系…

猫咪挑食怎么治?排行榜靠前适口性好的主食冻干推荐

在如今&#xff0c;养猫人士几乎都将自己的小猫咪视作珍宝&#xff0c;宠溺有加。但宠爱过度有时也会导致猫咪养成挑食的坏习惯。猫咪挑食怎么治呢&#xff1f;今天&#xff0c;我要分享一个既能让猫咪不受苦&#xff0c;又能纠正挑食问题的方法。 一、为什么猫会挑食呢&#x…

Linux调试器--gdb的介绍以及使用

文章目录 1.前言 ✒️2.介绍gdb✒️3.Debug模式和Release模式的区别✒️4.如何使用gdb✒️1️⃣.在debug模式下编译2️⃣.进入调试3️⃣ .调试命令集合⭐️⭐️ 1.前言 ✒️ &#x1f557;在我们之前的学习中已经学会了使用vim编译器编写c/c代码&#xff0c;但是对于一个程序员…

ThreadLocal出现内存泄露原因分析

ThreadLocal 导致内存泄漏的主要原因是它的工作方式。在 Java 中&#xff0c;ThreadLocal 通过维护一个以 Thread 为键&#xff0c;以用户设置的值为值的映射来工作。每个线程都拥有其自身的线程局部变量副本&#xff0c;不同线程间的这些变量互不干扰。这个映射是存储在每个 T…

sql-mysql可视化工具Workbench导入sql文件

mysql可视化工具Workbench导入sql文件 1、打开workbench2、导入sql文件3、第一行加上库名4、开始运行 1、打开workbench 2、导入sql文件 3、第一行加上库名 4、开始运行

Java学习笔记------拼图游戏

图形化界面GUI GUI&#xff1a;Graphical User Interface&#xff08;图像用户接口&#xff09;&#xff0c;指采用图形化的方式显示操作界面 两套体系&#xff1a;AWT包中和Swing包中 组件 JFrame&#xff1a;最外层的窗体 JMenuBar&#xff1a;最上层菜单 JLaber&#…

微信小程序开发系列(二十四)·wxml语法·列表渲染·wx:for-item 和 wx:for-index

目录 1. 如果需要对默认的变量名和下标进行修改&#xff0c;可以使用wx:for-item 和 wx:for-index 2. 将 wx:for 用在 标签上&#xff0c;以渲染一个包含多个节点的结构块 方法一 方法二 3. 总结 3.1 wx:for-item 和 wx:for-index总结 3.2 总结 1. 如果需要对默…

从mysql 数据库表导入数据到elasticSearch的几种方式

从MySQL数据库导入数据到Elasticsearch有几种方式&#xff0c;主要包括以下几种&#xff1a; 1. 使用Logstash&#xff1a; Logstash是一个开源的数据收集引擎&#xff0c;可以用来从不同的数据源导入数据到Elasticsearch。它具有强大的数据处理能力和插件生态系统&…

xlsx.js读取本地文件,按行转成数组数据

1.下包 //1. npm install xlsx //2. yarn add xlsx2.结构 <template><input type"file" change"onFileChange" /> </template>3.代码 <script> import * as XLSX from xlsxexport default {methods: {onFileChange (event) {/…

【“双碳”目标】Acrel-2000Z分布式光伏发电监测系统解决方案

1 概述 “十四五”期间&#xff0c;随着“双碳”目标提出及逐步落实&#xff0c;本就呈现出较好发展势头的分布式光伏发展有望大幅提速。就“十四五”光伏发展规划&#xff0c;国家发改委能源研究所可再生能源发展中心副主任陶冶表示&#xff0c;“双碳”目标意味着国家产业结…

【JS逆向学习】猿人学 第五题 js混淆 乱码

逆向目标 网址&#xff1a;https://match.yuanrenxue.cn/match/5接口&#xff1a;https://match.yuanrenxue.cn/api/match/5?page2&m1709806560791&f1709806560000参数&#xff1a; Cookie(m、RM4hZBv0dDon443M)payload(m、f) 逆向过程 老规矩&#xff0c;上来先分…

Java后端八股文之Redis

文章目录 1. Redis是什么&#xff1f;2. Redis为什么这么快&#xff1f;3. 为什么要使用缓存&#xff1f;4. Redis几种使用场景&#xff1a;5. Redis的Zset底层为什么要使用跳表而不是平衡树、红黑树或者B树&#xff1f;6.Redis持久化6.1 什么是RDB持久化6.1.1RDB创建快照会阻塞…

修改Android打包apk的名字和目录

app打包生成apk后通常需要进行备份&#xff0c;但是要区分好哪个apk是什么版本的、什么时候打包的&#xff0c;以方便以后区分使用。 最开始的想法是把版本号、创建时间这些加在apk文件名上即可&#xff0c;但是公司要求apk使用一个固定的名称&#xff0c;那我怎么保存版本号信…