使用 protobuf-java-util 实现 Protobuf 与 JSON 的无缝转换

常见技术问题 刘宇帅 6天前 阅读量: 20

在实际开发中,我们常常需要在 REST 接口(使用 JSON)与 gRPC 服务(使用 Protobuf)之间做数据转换。Google 提供的 protobuf-java-util 库,就是为了解决这个痛点而生的。它极大地简化了 Protobuf 对象与 JSON 之间的序列化与反序列化工作。

本文将介绍 protobuf-java-util 的核心功能、常见使用场景、并提供完整示例,帮助你在项目中快速上手。

一、什么是 protobuf-java-util

protobuf-java-util 是 Google 官方提供的一个 Protobuf 辅助工具库,主要功能包括:

  • ✅ Protobuf ↔ JSON 的互转
  • ✅ 支持 Timestamp、Any、Wrapper 类型的自动转换
  • ✅ 提供格式化选项(压缩、默认值输出等)

适用于任何由 protoc 编译生成的 Java Protobuf 类,也与 gRPC 生成的类完全兼容。

二、依赖引入

在 Maven 项目中添加如下依赖:

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java-util</artifactId>
    <version>3.11.0</version>
</dependency>

⚠️ 注意:protobuf-java-util 依赖于 protobuf-java,无需手动再引入。

三、核心类与功能

1. JsonFormat.printer()

将 Protobuf 对象转换为 JSON 字符串:

String json = JsonFormat.printer().print(protoObject);

可选配置:

  • .includingDefaultValueFields():输出所有字段,即使是默认值
  • .omittingInsignificantWhitespace():压缩 JSON,无缩进空格
  • .preservingProtoFieldNames():使用 Protobuf 字段名(默认使用驼峰)

2. JsonFormat.parser()

将 JSON 字符串反序列化为 Protobuf 对象:

YourMessage.Builder builder = YourMessage.newBuilder();
JsonFormat.parser().merge(jsonString, builder);
YourMessage message = builder.build();

四、使用示例

示例:定义一个简单的消息

// user.proto
syntax = "proto3";

message User {
  string name = 1;
  int32 age = 2;
}

使用 protoc 编译生成 User.java,我们可以这样完成 JSON 与 Protobuf 的互转:

import com.google.protobuf.util.JsonFormat;

String json = "{\"name\": \"Alice\", \"age\": 30}";

// JSON → Protobuf
User.Builder builder = User.newBuilder();
JsonFormat.parser().merge(json, builder);
User user = builder.build();

// Protobuf → JSON
String outputJson = JsonFormat.printer()
    .includingDefaultValueFields()
    .print(user);

System.out.println(outputJson);

输出结果:

{
  "name": "Alice",
  "age": 30
}

五、常见进阶用法

1. 支持 google.protobuf.Timestamp

如果你的消息中包含时间字段:

import "google/protobuf/timestamp.proto";

message Event {
  string title = 1;
  google.protobuf.Timestamp created_at = 2;
}

转换时会自动识别 ISO8601 格式时间:

{
  "title": "Launch",
  "createdAt": "2024-05-13T12:00:00Z"
}

无需额外处理,protobuf-java-util 会自动完成 Timestamp 与时间字符串之间的转换。

2. 支持 google.protobuf.Any

Any 类型字段可以嵌套任意消息,protobuf-java-util 也能识别:

import "google/protobuf/any.proto";

message Wrapper {
  google.protobuf.Any payload = 1;
}

在 JSON 中表现为:

{
  "payload": {
    "@type": "type.googleapis.com/your.package.User",
    "name": "Alice",
    "age": 25
  }
}

六、使用建议与注意事项

建议 / 限制 说明
✅ 可与 REST API 搭配使用 可用于 Spring Boot 接收 JSON,转为 gRPC 参数
✅ 自动处理嵌套消息 嵌套对象可完整转换,无需手动处理
❌ 不支持 Jackson/Gson 注解 与常规 JSON 序列化工具无兼容性
⚠️ Builder 模式必须使用 merge() 只能用于 Protobuf 的 Builder,不是 Message

七、典型应用场景

  • ? 网关服务接收 JSON → 转换为 Protobuf → 调用 gRPC
  • ? 日志记录 gRPC 返回的 Protobuf → 转换为 JSON 存储
  • ? 第三方 API 返回 JSON → 合并为 Protobuf 对象发往服务层

八、总结

protobuf-java-util 是连接 JSON 与 Protobuf 的高效桥梁。它帮助我们轻松完成数据格式转换,特别适用于 gRPC 与 REST 混用架构,在现代微服务场景中非常实用。

无论你是做服务对接、数据转换、还是开发调试,掌握这个工具都能大大提升开发效率。

提示

功能待开通!


暂无评论~