Springboot集成Protobuf的流程步驟
1、前言
在以往的項目中進行網(wǎng)絡(luò)通信和數(shù)據(jù)交換的應(yīng)用場景中,最經(jīng)常使用的技術(shù)便是json或xml。隨著JSON的靈活優(yōu)勢,越來越多的企業(yè)選擇JSON作為數(shù)據(jù)交換的格式,目前JSON已經(jīng)成為了業(yè)界的主流。JSON已經(jīng)足夠好用,且能滿足相當大部分的場景。但是今天在介紹一個Google的力作protobuf作為數(shù)據(jù)交換格式。我們來看看。
2、Protobuf簡介
Github地址:GitHub - protocolbuffers/protobuf: Protocol Buffers - Google's data interchange format
官網(wǎng)地址:Overview | Protocol Buffers Documentation
Protobuf(Protocol Buffers)是由 Google 開發(fā)的一種輕量級、高效的數(shù)據(jù)交換格式,它被用于結(jié)構(gòu)化數(shù)據(jù)的序列化、反序列化和傳輸。相比于 XML 和 JSON 等文本格式,Protobuf 具有更小的數(shù)據(jù)體積、更快的解析速度和更強的可擴展性。同時他是一種語言無關(guān)、平臺無關(guān)、可擴展的序列化格式。它使開發(fā)人員能夠在文件中定義結(jié)構(gòu)化數(shù)據(jù).proto,然后使用該文件生成可以從不同數(shù)據(jù)流寫入和讀取數(shù)據(jù)的源代碼。
2.1、核心思想
Protobuf 核心思想是使用協(xié)議來定義數(shù)據(jù)的結(jié)構(gòu)和編碼方式。協(xié)議是一個文本文件,其中定義了消息的結(jié)構(gòu)。消息由字段組成,每個字段都有一個名稱、類型和可選的默認值。然后使用Protobuf提供的解碼器生成對應(yīng)代碼,用于序列化和反序列化數(shù)據(jù),由于Protobuf是基于二進制編碼,因此可以跨語言使用。
Protobuf 支持以下數(shù)據(jù)類型:
- 基本類型:例如 int32、string、bool 等
- 復(fù)合類型:例如 message、enum 等
2.2、Protobuf是如何工作的?
Protobuf 使用二進制數(shù)據(jù)格式,與基于文本的格式相比,它更緊湊且讀寫速度更快。它還提供了接口定義語言(IDL),可以輕松定義要序列化的數(shù)據(jù)的結(jié)構(gòu)。
Protobuf 文件使用文件擴展名保存.proto。該.proto文件以 Protobuf 的 IDL 格式編寫,包含有關(guān)數(shù)據(jù)結(jié)構(gòu)的所有信息。數(shù)據(jù)被建模為“消息”,即名稱/值對組。以下是文件中簡單 Protobuf 消息的示例.proto:
// 指定 Protobuf 版本為版本 3(最新版本) syntax = "proto3"; // 指定protobuf包名,防止類名重復(fù) package com.shamee.protobuf; // 生成的文件存放在哪個包下 option java_package = "com.shamee.protos"; // 生成的類名,如果沒有指定,會根據(jù)文件名自動轉(zhuǎn)駝峰來命名 option java_outer_classname = "PersonProtos"; // 定義了一個Person類 message Person { // 后面的值(=1 =2)作為序列化后的二進制編碼中的字段的唯一標簽 // 因此 1-15比 16 會少一個字節(jié),所以盡量使用 1-15 來指定常用字段。 int32 id = 1; string name = 2; string email = 3; string address = 4; }
示例中,客戶消息包含四個字段:id、name、email和address。每個字段都有其類型指示,以及指示其是否為required、optional或 的標簽repeated。
該.proto文件可以使用 Protoc(即 Protobuf 編譯器)編譯成多種編程語言。該編譯器以開發(fā)人員指定的編程語言生成源代碼。該源代碼包括用于寫入、讀取和操作.proto文件中定義的消息類型的類和方法。
當有數(shù)據(jù)要存儲或傳輸時,可以創(chuàng)建生成的類的實例并用您的數(shù)據(jù)填充它們。然后將這些實例序列化為二進制格式。讀取數(shù)據(jù)時,二進制格式將反序列化回從.proto文件生成的類的實例。這使您可以輕松訪問結(jié)構(gòu)化數(shù)據(jù)。
Protobuf 生成的二進制數(shù)據(jù)格式是平臺無關(guān)的,可用于在不同系統(tǒng)、應(yīng)用程序或服務(wù)之間交換數(shù)據(jù),即使它們是用不同的編程語言實現(xiàn)或在不同的平臺上運行的。
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的基本內(nèi)容,以及簡單的語法編寫和編譯。接下來我們來使用他,并集成到我們的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文件,一個用于接收接口請求數(shù)據(jù)Person.proto,一個用于響應(yīng)Response.proto。
Person.proto:
syntax = "proto3"; package proto.shamee; // 生成的文件存放在哪個包下 option java_package = "proto.shamee"; // 生成的類名,如果沒有指定,會根據(jù)文件名自動轉(zhuǎn)駝峰來命名 option java_outer_classname = "PersonProto"; // 定義了一個Person類 message Person { // 后面的值(=1 =2)作為序列化后的二進制編碼中的字段的唯一標簽 // 因此 1-15比 16 會少一個字節(jié),所以盡量使用 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,可以生成響應(yīng)的proto的java代碼。
3.4、配置Protobuf的序列化和反序列化
@Configuration public class ProtobufConfig { /** * protobuf 序列化 */ @Bean ProtobufHttpMessageConverter protobufHttpMessageConverter() { return new ProtobufHttpMessageConverter(); } /** * protobuf 反序列化 */ @Bean RestTemplate restTemplate(ProtobufHttpMessageConverter protobufHttpMessageConverter) { return new RestTemplate(Collections.singletonList(protobufHttpMessageConverter)); } }
3.5、定義controller接口
由于protobuf是基于二進制流傳輸數(shù)據(jù),因此這里需要指定一下x-protobuf協(xié)議。
@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,同時參數(shù)以二進制數(shù)據(jù)進行傳輸訪問。我們的請求數(shù)據(jù):
訪問頭配置:
返回:
到此我們就簡單的學會了protobuf了
4、小結(jié)
protobuf在整個集成中還是有一些問題,如ptotoc的版本號如果相差太多就會編譯不通過。當然protobuf也存在一些不足之處:
功能簡單:Protobuf 功能簡單,無法用來表示復(fù)雜的概念。例如,它無法表示 XML 中的DTD 或 XSD 等復(fù)雜結(jié)構(gòu)。
通用性較差:Protobuf 是 Google 內(nèi)部使用的工具,通用性較差。XML 和 JSON 已成為多種行業(yè)標準的編寫工具,而 Protobuf 在通用性上還差很多。
自解釋性差:Protobuf 以二進制形式存儲數(shù)據(jù),不便于閱讀和編輯。XML 具有自解釋性,可以直接用文本編輯器打開和編輯。
Protobuf 是一種優(yōu)秀的序列化格式,但并非完美無缺。在選擇序列化格式時,需要根據(jù)實際需求進行綜合考慮。如果需要一種高效、緊湊、可擴展的序列化格式,Protobuf 是一個不錯的選擇。但如果需要表示復(fù)雜的概念、通用性或自解釋性,則需要考慮其他序列化格式。
以上就是Springboot集成Protobuf的流程步驟的詳細內(nèi)容,更多關(guān)于Springboot集成Protobuf的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java?byte數(shù)組轉(zhuǎn)String的幾種常用方法
在Java中數(shù)組是一種非常常見的數(shù)據(jù)結(jié)構(gòu),它可以用來存儲多個相同類型的數(shù)據(jù),有時候,我們需要將數(shù)組轉(zhuǎn)換為字符串,以便于輸出或者傳遞給其他方法,這篇文章主要給大家介紹了關(guān)于java?byte數(shù)組轉(zhuǎn)String的幾種常用方法,需要的朋友可以參考下2024-09-09詳解SpringBoot與SpringCloud的版本對應(yīng)詳細版
這篇文章主要介紹了詳解SpringBoot與SpringCloud的版本對應(yīng)詳細版,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09Spring Boot + thymeleaf 實現(xiàn)文件上傳下載功能
最近同事問我有沒有有關(guān)于技術(shù)的電子書,我打開電腦上的小書庫,但是郵件發(fā)給他太大了,公司又禁止用文件夾共享,于是花半天時間寫了個小的文件上傳程序,部署在自己的Linux機器上,需要的朋友可以參考下2018-01-01解決maven打包排除類不生效maven-compiler-plugin問題
總結(jié):在Spring Boot項目B中作為項目A的依賴時,排除啟動類不生效的原因是被其他類引用或父POM引入,解決方法是跳過test編譯或注釋掉@SpringBootTest(classes={BApplication.class})2024-11-11java中ArrayList和LinkedList的區(qū)別詳解
這篇文章主要介紹了java中ArrayList和LinkedList的區(qū)別詳解,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2021-01-01