13. Springboot集成Protobuf

目录

1、前言

2、Protobuf简介

2.1、核心思想

2.2、Protobuf是如何工作的?

2.3、如何使用 Protoc 生成代码?

3、Springboot集成

3.1、引入依赖

3.2、定义Proto文件

3.3、Protobuf生成Java代码

3.4、配置Protobuf的序列化和反序列化

3.5、定义controller接口

3.6、访问

4、小结


1、前言

在以往的项目中进行网络通信和数据交换的应用场景中,最经常使用的技术便是json或xml。随着JSON的灵活优势,越来越多的企业选择JSON作为数据交换的格式,目前JSON已经成为了业界的主流。JSON已经足够好用,且能满足相当大部分的场景。但是今天在介绍一个Google的力作protobuf作为数据交换格式。我们来看看。

2、Protobuf简介

Github地址:GitHub - protocolbuffers/protobuf: Protocol Buffers - Google's data interchange format

官网地址:Overview | Protocol Buffers Documentation

Protobuf(Protocol Buffers)是由 Google 开发的一种轻量级、高效的数据交换格式,它被用于结构化数据的序列化、反序列化和传输。相比于 XML 和 JSON 等文本格式,Protobuf 具有更小的数据体积、更快的解析速度和更强的可扩展性。同时他是一种语言无关、平台无关、可扩展的序列化格式。它使开发人员能够在文件中定义结构化数据.proto,然后使用该文件生成可以从不同数据流写入和读取数据的源代码。

2.1、核心思想

Protobuf 核心思想是使用协议来定义数据的结构和编码方式。协议是一个文本文件,其中定义了消息的结构。消息由字段组成,每个字段都有一个名称、类型和可选的默认值。然后使用Protobuf提供的解码器生成对应代码,用于序列化和反序列化数据,由于Protobuf是基于二进制编码,因此可以跨语言使用。

Protobuf 支持以下数据类型:

  • 基本类型:例如 int32、string、bool 等
  • 复合类型:例如 message、enum 等

2.2、Protobuf是如何工作的?

Protobuf 使用二进制数据格式,与基于文本的格式相比,它更紧凑且读写速度更快。它还提供了接口定义语言(IDL),可以轻松定义要序列化的数据的结构。

Protobuf 文件使用文件扩展名保存.proto。该.proto文件以 Protobuf 的 IDL 格式编写,包含有关数据结构的所有信息。数据被建模为“消息”,即名称/值对组。以下是文件中简单 Protobuf 消息的示例.proto:

// 指定 Protobuf 版本为版本 3(最新版本)
syntax = "proto3";// 指定protobuf包名,防止类名重复
package com.shamee.protobuf;// 生成的文件存放在哪个包下
option java_package = "com.shamee.protos";// 生成的类名,如果没有指定,会根据文件名自动转驼峰来命名
option java_outer_classname = "PersonProtos";// 定义了一个Person类
message Person {// 后面的值(=1  =2)作为序列化后的二进制编码中的字段的唯一标签// 因此 1-15比 16 会少一个字节,所以尽量使用 1-15 来指定常用字段。int32 id = 1;string name = 2;string email = 3;string address = 4;
}

示例中,客户消息包含四个字段:id、name、email和address。每个字段都有其类型指示,以及指示其是否为required、optional或 的标签repeated。

该.proto文件可以使用 Protoc(即 Protobuf 编译器)编译成多种编程语言。该编译器以开发人员指定的编程语言生成源代码。该源代码包括用于写入、读取和操作.proto文件中定义的消息类型的类和方法。

当有数据要存储或传输时,可以创建生成的类的实例并用您的数据填充它们。然后将这些实例序列化为二进制格式。读取数据时,二进制格式将反序列化回从.proto文件生成的类的实例。这使您可以轻松访问结构化数据。

Protobuf 生成的二进制数据格式是平台无关的,可用于在不同系统、应用程序或服务之间交换数据,即使它们是用不同的编程语言实现或在不同的平台上运行的。

2.3、如何使用 Protoc 生成代码?

上面定义好的.proto,可以使用Protobbuf编译器(Protoc)将文件编译成不同语言。

下载编译器:Release Protocol Buffers v25.3 · protocolbuffers/protobuf · GitHub

编译命令如下面的代码将.proto文件编译成 JavaScript:

protoc --js_out=import_style=commonjs,binary: .customers.proto

编译成java语言:

protoc --java_out=./my_dist  .customers.proto

3、Springboot集成

上面介绍了protobuf的基本内容,以及简单的语法编写和编译。接下来我们来使用他,并集成到我们的springboot中。

3.1、引入依赖

<dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>3.6.1</version>
</dependency>
<!-- 同时添加maven插件,用于编译protobuf生成java文件 -->
<build><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.5.0.Final</version></extension></extensions><plugins><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.5.0</version><configuration><protocArtifact>com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}</protocArtifact><!--默认值,proto源文件路径--><protoSourceRoot>${project.basedir}/src/main/resources/proto</protoSourceRoot><pluginId>grpc-java</pluginId><!--是否清空上面配置目录outputDirectory--><clearOutputDirectory>false</clearOutputDirectory></configuration><executions><execution><goals><goal>compile</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.3.0</version><configuration><excludes><exclude>**/*.proto</exclude></excludes></configuration></plugin></plugins>
</build>

3.2、定义Proto文件

定义两个proto文件,一个用于接收接口请求数据Person.proto,一个用于响应Response.proto。

Person.proto:

syntax = "proto3";
package proto.shamee;// 生成的文件存放在哪个包下
option java_package = "proto.shamee";// 生成的类名,如果没有指定,会根据文件名自动转驼峰来命名
option java_outer_classname = "PersonProto";// 定义了一个Person类
message Person {// 后面的值(=1  =2)作为序列化后的二进制编码中的字段的唯一标签// 因此 1-15比 16 会少一个字节,所以尽量使用 1-15 来指定常用字段。int32 id = 1;string name = 2;string email = 3;string address = 4;
}

Response.proto:

syntax = "proto3";
package proto.shamee;
option java_package = "proto.shamee";
option java_outer_classname = "ResponseProto";message Response {int32 code = 1;string message = 2;string data = 3;
}

3.3、Protobuf生成Java代码

定义完后,可以直接mvn install,可以生成响应的proto的java代码。

3.4、配置Protobuf的序列化和反序列化

@Configuration
public class ProtobufConfig {/*** protobuf 序列化*/@BeanProtobufHttpMessageConverter protobufHttpMessageConverter() {return new ProtobufHttpMessageConverter();}/*** protobuf 反序列化*/@BeanRestTemplate restTemplate(ProtobufHttpMessageConverter protobufHttpMessageConverter) {return new RestTemplate(Collections.singletonList(protobufHttpMessageConverter));}}

3.5、定义controller接口

由于protobuf是基于二进制流传输数据,因此这里需要指定一下x-protobuf协议。

@RestController
@RequestMapping("/test")
public class TestController {@PostMapping(value = "/index", produces = "application/x-protobuf")public ResponseProto.Response index(@RequestBody PersonProto.Person person){return ResponseProto.Response.newBuilder().setCode(200).setMessage("OK").setData("hello:" + person.getName()).build();}}

接着就可以启动springboot项目啦。

3.6、访问

这里访问的时候,需要定义header的content-type,同时参数以二进制数据进行传输访问。我们的请求数据:

访问头配置:

返回:

到此我们就简单的学会了protobuf了,又可以安心的去吃夜宵了。

4、小结

protobuf在整个集成中还是有一些问题,如ptotoc的版本号如果相差太多就会编译不通过。当然protobuf也存在一些不足之处:

  • 功能简单:Protobuf 功能简单,无法用来表示复杂的概念。例如,它无法表示 XML 中的DTD 或 XSD 等复杂结构。
  • 通用性较差:Protobuf 是 Google 内部使用的工具,通用性较差。XML 和 JSON 已成为多种行业标准的编写工具,而 Protobuf 在通用性上还差很多。
  • 自解释性差:Protobuf 以二进制形式存储数据,不便于阅读和编辑。XML 具有自解释性,可以直接用文本编辑器打开和编辑。

Protobuf 是一种优秀的序列化格式,但并非完美无缺。在选择序列化格式时,需要根据实际需求进行综合考虑。如果需要一种高效、紧凑、可扩展的序列化格式,Protobuf 是一个不错的选择。但如果需要表示复杂的概念、通用性或自解释性,则需要考虑其他序列化格式。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

烧脑问题解决办法:如何选择一款合适自己的手机流量卡

现在社会人们越来越离不开手机了&#xff0c;手机给我们生活带来了翻天覆地的变化&#xff0c;手机需要最多的就是流量了&#xff0c;所以选择一款合适自己的手机流量卡就显得尤为重要了&#xff0c;今天小编就给大家来分享一下我的经验&#xff0c;希望对大家能有帮助&#xf…

【机器学习】FashionMNIST数据集简介及下载方法(自动下载)

【机器学习】FashionMNIST数据集简介及下载方法(自动下载) &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订…

[c 语言] 大端,小端;网络序,主机序

在网络编程中&#xff0c;特别是底层网卡驱动开发时&#xff0c;常常遇到字节序问题。字节序指的是多字节数据类型在内存中存放的顺序&#xff0c;高位保存在低地址还是高地址&#xff0c;以此来划分大端还是小端。 1 大端和小端 大端和小端指的是 cpu 的属性&#xff0c;常见…

Linux命名管道

Linux匿名管道-CSDN博客 目录 1.原理 2.接口实现 3.模拟日志 Linux匿名管道-CSDN博客 这上面叫的是匿名管道&#xff0c;不要将两者搞混&#xff0c;匿名管道说的是两个有血缘关系的进程相互通信&#xff0c;但是命名管道就是两个没有关系的管道相互通信。 1.原理 和匿名…

智能驾驶规划控制理论学习03-基于采样的规划方法

目录 一、基于采样的规划方法概述 二、概率路图&#xff08;PRM&#xff09; 1、核心思想 2、实现流程 3、算法描述 4、节点连接处理 5、总结 三、快速搜索随机树&#xff08;RRT&#xff09; 1、核心思想 2、实现流程 3、总结 4、改进RRT算法 ①快速搜索随机图&a…

Docker知识点总结二

四、 Docker 架构 Docker使用客户端-服务器(C/S)架构模式&#xff0c;使用远程API来管理和创建Docker容器。 介绍&#xff1a; 1、Docker的客户端client&#xff0c;我们在命令行发送一些信息(命令)给Docker服务端。2、中间这个就是Docker的服务端&#xff0c;在这个服务端里面…

优选算法|【双指针】|1089.复写零

目录 题目描述 题目解析 算法原理讲解 代码 题目描述 1089. 复写零 给你一个长度固定的整数数组 arr &#xff0c;请你将该数组中出现的每个零都复写一遍&#xff0c;并将其余的元素向右平移。 注意&#xff1a;请不要在超过该数组长度的位置写入元素。请对输入的数组 就…

初学者如何快速搭建基于 Selenium Grid 的分布式自动化

Selenium Grid是一个测试工具&#xff0c;它允许我们在不同的机器上针对不同的浏览器运行测试。 配置Hub 为了简单起见&#xff0c;我们将只使用一台机器来设置Hub&#xff0c;并在同一台机器上设置Node来运行测试。 1.需要安装Java 11或更高版本 2.需要安装浏览器 3.需要…

【Python】进阶学习:pandas--isin()用法详解

【Python】进阶学习&#xff1a;pandas–isin()用法详解 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订阅…

【简略知识】项目开发中,VO,BO,PO,DO,DTO究竟是何方妖怪?

前言 在项目开发中&#xff0c;是否需要定义VO&#xff08;视图对象&#xff09;&#xff0c;BO&#xff08;业务对象&#xff09;&#xff0c;PO&#xff08;持久化对象&#xff09;&#xff0c;DO&#xff08;领域对象&#xff09;&#xff0c;DTO&#xff08;数据传输对象&…

2.1 mov、add和sub加减指令实操体验

汇编语言 1. mov操作 1.1 mov移动值 mov指令把右边的值移动到左边 mount c d:masm c: debug r ax 0034 r 073f:0100 mov ax,7t1.2 mov移动寄存器的值 把右边寄存器的值赋值给左边的寄存器 a 073f:0105 mov bx,axt1.3 mov高八位&#xff08;high&#xff09;和低八位&am…

求职招聘类App如何打造的更卓越:解析关键功能和发展趋势

随着人才市场的竞争日益激烈&#xff0c;求职招聘类App成为现代职场中不可或缺的工具。对您来说&#xff0c;一款卓越的求职招聘类App满足您用户的多样化需求是很有必要的。在这篇文章中&#xff0c;我们将深入探讨其关键功能和行业发展趋势&#xff0c;助您的App在市场中脱颖而…