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