【Protobuf】Springboot集成protobuf
定义两个proto文件,一个用于接收接口请求数据 Student.proto,一个用于响应 Response.proto。Tips:对于新手来说,定义的这个 .proto 文件还不知道放在哪个目录下。注意:此文件是放在静态资源 resources 目录下。// 指定 Protobuf 版本为版本 3(最新版本)// 指定protobuf包名,防止类名重复// 生成的文件存放在哪个包下,对于新手来说
Springboot集成protobuf
上一篇文章我们介绍了protobuf的基本内容,以及简单的语法编写和编译。接下来我们来使用这技术,并集成到我们的springboot中。
一、技术栈
Spring boot(v2.3.0.RELEASE) + protobuf(proto3) + protobuf-java(3.8.0)
二、集成步骤
2.1 引入依赖
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.8.0</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>
完整项目代码请移步至 gitee 上:spring-boot-all-demo
2.2 定义Proto文件
定义两个proto文件,一个用于接收接口请求数据 Student.proto,一个用于响应 Response.proto。
Tips:对于新手来说,定义的这个 .proto 文件还不知道放在哪个目录下。注意:此文件是放在静态资源 resources 目录下。
以下是Student.proto 文件:
// 指定 Protobuf 版本为版本 3(最新版本)
syntax = "proto3";
// 指定protobuf包名,防止类名重复
package com.iot.protobuf;
// 生成的文件存放在哪个包下,对于新手来说,不指定生成到哪个目录下即可,不建议指定包(否则,可能让你怀疑人生)
option java_package = "com.example.hjm.udp.proto";
// 生成的类名,如果没有指定,会根据文件名自动转驼峰来命名
option java_outer_classname = "StudentProto";
// 定义了一个Student类
message Student {
// 后面的值(1、2、3、4等)作为序列化后的二进制编码中的字段的唯一标签
// 因为 1-15比 16 会少一个字节,所以尽量使用 1-15 来指定常用字段。
int32 id = 1;
string name = 2;
string email = 3;
string address = 4;
}
以下是 Response.proto 文件:
syntax = "proto3";
package proto;
option java_package = "com.example.hjm.udp.proto";
option java_outer_classname = "ResponseProto";
message Response {
int32 code = 1;
string message = 2;
string data = 3;
}
2.3 Protobuf生成Java代码
定义完后,可以直接mvn install,可以生成响应的proto的java代码。
2.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));
}
}
2.5 定义controller接口
由于protobuf是基于二进制流传输数据,因此这里需要指定一下x-protobuf协议。
@RestController
@RequestMapping("/test")
public class TestController {
@PostMapping(value = "/index", produces = "application/x-protobuf")
public ResponseProto.Response index(@RequestBody StudentProto.Student student){
return ResponseProto.Response.newBuilder()
.setCode(200)
.setMessage("OK")
.setData("hello:" + student.getName()).build();
}
}
接着就可以启动springboot项目啦。
2.6 访问
这里访问的时候,需要定义header的content-type,同时参数以二进制数据进行传输访问。我们的请求数据:
到此我们就简单的学会了protobuf了。
三、Springboot集成protobuf总结
protobuf在整个集成中还是有一些问题,如ptotoc的版本号如果相差太多就会编译不通过。当然protobuf也存在一些不足之处:
功能简单:Protobuf 功能简单,无法用来表示复杂的概念。例如,它无法表示 XML 中的DTD 或 XSD 等复杂结构。
通用性较差:Protobuf 是 Google 内部使用的工具,通用性较差。XML 和 JSON 已成为多种行业标准的编写工具,而 Protobuf 在通用性上还差很多。
自解释性差:Protobuf 以二进制形式存储数据,不便于阅读和编辑。XML 具有自解释性,可以直接用文本编辑器打开和编辑。
Protobuf 是一种优秀的序列化格式,但并非完美无缺。在选择序列化格式时,需要根据实际需求进行综合考虑。如果需要一种高效、紧凑、可扩展的序列化格式,Protobuf 是一个不错的选择。但如果需要表示复杂的概念、通用性或自解释性,则需要考虑其他序列化格式。
本文完结!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)