环境版本
不同的环境配置参数可能区别较大,请酌情参考。
插件或依赖 | 版本号 |
---|---|
SpringBoot | 2.7.10 |
Gradle | 7.5.1 |
Protobuf Gradle Plugin | 0.9.2 |
Protobuf Java | 3.21.9 |
Protoc | 3.21.9 |
Grpc | 1.53.0 |
项目是使用 IDEA 创建的 Spring Web 项目,语言 Kotlin,构建 Gradle
Protobuf 手动配置
Protobuf 的目的是将数据序列化,它提供了完善的编码工具:Protoc,可以将 .proto 定义的文件方便地转换为所需语言的类文件。
比如:Kotlin 使用 Protobuf,手动配置的流程如下:
graph TB
A(创建 .proto 文件) --> B(运行 protoc 命令将 .proto 文件转换为 .kt 文件)
B --> C(使用 .kt 类方法进行序列化)
但是,实践结果是生成的 .kt 文件有错误,可能是 Kotlin 版本问题。 用起来也不是很方便,所以采用 gradle plugin 的方式自动管理包和编译Proto。
添加插件和依赖
在 build.gradle.kts 中配置 Protobuf 需要的插件和依赖。
添加 protobuf gralde plugin
plugins {
...
id("com.google.protobuf") version "0.9.2"
}
该插件帮助管理 protoc 和完成文件转换。
Protobuf Gradle Plugin 的源码地址: https://github.com/google/protobuf-gradle-plugin
添加 Protobuf 的依赖包
dependencies {
...
implementation("com.google.protobuf:protobuf-java:3.21.9")
implementation("io.grpc:grpc-protobuf:1.53.0")
implementation("io.grpc:grpc-stub:1.53.0")
}
配置 Protobuf 插件
protobuf {
// 配置 protoc
protoc {
artifact = "com.google.protobuf:protoc:3.21.9"
}
// 配置 grpc
plugins {
// 这里需要加 id,旧版本可能是这样: grpc {}
id("grpc"){
artifact = "io.grpc:protoc-gen-grpc-java:1.53.0"
}
}
// 配置 gradle task
generateProtoTasks {
ofSourceSet("main").forEach {
it.plugins {
id("grpc") { }
}
}
}
}
编写 .proto 文件
文件位置
在 src/main目录下新建目录 proto,然后在该目录下新建包名和 .proto 文件。 示例目录结构如下:
src
└─ main
├─kotlin
│ └─cn.test.proj
├─proto
│ └─cn.test.proj
│ Param.proto
│
└─resources
proto 与 kotlin 在同一级,.proto 文件在相同的包下。
proto 文件编写
这里是简单示例,详细内容,请参考 proto 官方文档。
syntax = "proto3";
package cn.test.proj;
message Person {
string id = 1;
string name = 2;
}
package 值与目录中的包名对应
使用方法
生成 Proto 对象
在 IDEA 右侧 Gradle 窗口,执行 Tasks - other - generateProto 任务,生成 Proto 对象。
使用 Proto 对象
不像手动运行 protoc 命令会生成 .kt 文件。运行 generateProto task 之后,项目文件中没有看到对应的 .kt 文件生成,但是可以像使用 Kotlin 对象一样使用 proto 对象。
参照上文示例,我们在 Param.proto 中定义了一个 Person 对象,如果使用 Okhttp3 请求网络服务,参数是 Person,响应参数也是 Person 示例代码如下:
private const val CONTENT_TYPE = "application/x-protobuf"
fun request(){
val requestPerson = Param.Person.newBuilder().apply{
id = "testid"
name = "Peter"
}.build()
val requestBytes = requestPerson.toByteArray() // 序列化
val requestBody = requestBytes.toRequestBody(CONTENT_TYPE.toMediaType())
...
// Okhttp 请求
// header 中添加 "Content-Type" = CONTENT_TYPE
// 请求响应结果 response: Response
...
val responseBytes = response.body?.bytes()
val responsePerson = Param.Person.parseFrom(responseBytes) // 反序列化
}
标签:文件,SpringBoot,protoc,protobuf,proto,grpc,Kotlin,Protobuf
From: https://blog.51cto.com/u_15777791/6209498