博客
关于我
protobuf对象与JSON相互转换
阅读量:795 次
发布时间:2023-03-04

本文共 3854 字,大约阅读时间需要 12 分钟。

protobuf与JSON转换实践指南

一、protobuf Java依赖管理

在使用protobuf进行数据序列化和反序列化时,需要注意以下依赖管理:

  • 基础依赖:引入protobuf-java,通常选择稳定版本进行使用。
  • 辅助工具:引入protobuf-java-util,提供对proto对象进行转换的便利方法。
  • 以下是Maven项目中常用的依赖配置:

    com.google.protobuf
    protobuf-java
    3.19.1
    com.google.protobuf
    protobuf-java-util
    3.19.1

    二、默认值处理注意事项

    在使用protobuf时,默认值的处理需要特别注意以下几点:

  • 标量类型字段:一旦解析完成,无法判断字段是否为显式设置,默认值会被省略在序列化输出中。
  • 显式设置默认值:如果在定义字段时显式设置默认值,系统将忽略该值进行序列化。
  • JSON转proto转换:当JSON字符串中包含显式设置的默认值时,转换为proto对象时会被忽略。
  • 三、proto对象转JSON串

    要将protobuf对象转换为JSON格式,可以使用JsonFormat工具。以下是常用操作步骤:

  • 序列化过程

    // 获取打印器JsonFormat.Printer printer = JsonFormat.printer();// 定义打印规则printer.includingDefaultValueFields(); // 包含默认值字段printer.preservingProtoFieldNames(); // 保持原字段名称// 开始打印String userJsonStr = printer.print(user);
  • JSON字段名称与字段名的对应关系

    • includingDefaultValueFields():决定是否包含默认值字段。
    • preservingProtoFieldNames():决定是否使用proto文件中的原始字段名称。
  • 四、JSON串转proto对象

    将JSON串转换为protobuf对象时,可以使用JsonFormat解析器:

  • 解析过程

    // 获取解析器JsonFormat.Parser parser = JsonFormat.parser();// 定义解析规则parser.ignoringUnknownFields(); // 忽略未知字段// 开始解析UserProtoBuf.User.Builder userBuilder = UserProtoBuf.User.newBuilder();parser.merge(userJsonStr2, userBuilder);
  • 字段处理规则

    • ignoringUnknownFields():如果JSON中存在未知字段,选择忽略或抛出异常。
  • 五、示例实战

    以下是一个完整的实例说明,帮助您理解protobuf与JSON的转换流程。

    proto文件定义

    syntax = "proto3";option java_outer_classname = "UserProtoBuf";message User {    int32 age = 1;    int64 timestamp = 2;    bool enabled = 3;    float height = 4;    double weight = 5;    string userName = 6;    string Full_Address = 7;}

    代码示例

    import com.google.protobuf.util.JsonFormat;public class UserTest {    public static void main(String[] args) throws Exception {        // 模拟发送方数据        byte[] byteData = getClientPush();        // 反序列化为对象        UserProtoBuf.User user = UserProtoBuf.User.parseFrom(byteData);        // 打印用户信息        System.out.println("用户信息:");        System.out.println(user);        System.out.println("年龄:" + user.getAge());        System.out.println("时间戳:" + user.getTimestamp());        System.out.println("是否启用:" + user.getEnabled());        System.out.println("高度:" + user.getHeight());        System.out.println("重量:" + user.getWeight());        System.out.println("用户名:" + user.getUserName());        System.out.println("地址:" + user.getFullAddress());        // proto对象转JSON        String userJsonStr = JsonFormat.printer()                .includingDefaultValueFields()                .print(user);        System.out.println("\nJSON字符串:" + userJsonStr);        // JSON转proto对象        String userJsonStr2 = "{\n" +                "    \"age\":18,\n" +                "    \"timestamp\":\"1698377283315\",\n" +                "    \"enabled\":false,\n" +                "    \"height\":1.8,\n" +                "    \"weight\":66.76,\n" +                "    \"userName\":\"赵云\"\n" +                "}";        UserProtoBuf.User.Builder userBuilder = UserProtoBuf.User.newBuilder();        JsonFormat.parser()                .ignoringUnknownFields()                .merge(userJsonStr2, userBuilder);        UserProtoBuf.User user1 = userBuilder.build();        System.out.println("\n转换后的用户对象:");        System.out.println(user1);    }    private static byte[] getClientPush() {        UserProtoBuf.User.Builder user = UserProtoBuf.User.newBuilder();        user.setAge(18);        user.setTimestamp(System.currentTimeMillis());        user.setEnabled(false);        user.setWeight(66.76);        user.setUserName("赵云");        return user.build().toByteArray();    }}

    六、优化建议

  • 默认值处理:在定义消息类型时,避免使用布尔值默认为false来控制某些行为,除非你希望这种行为在默认情况下生效。
  • JSON格式输出:使用includingDefaultValueFields()确保所有字段(包括默认值)都被包含在输出中。
  • 字段名称保留:使用preservingProtoFieldNames()确保字段名称与proto文件中的定义一致。
  • 解析规则:在解析JSON时,使用ignoringUnknownFields()来处理可能存在的未知字段,以避免异常。
  • 通过以上方法,您可以顺利地进行protobuf与JSON的转换操作,确保数据在双向传输过程中的准确性和完整性。

    转载地址:http://bgxfk.baihongyu.com/

    你可能感兴趣的文章
    Postman接口自动化测试之——批量参数化(参数文件)
    查看>>
    Postman接口自动化测试之——批量执行(集合操作)
    查看>>
    Postman接口自动化测试之——批量执行(集合操作)
    查看>>
    Postman断言与依赖接口测试详解!
    查看>>
    Postman环境变量以及设置token全局变量!
    查看>>
    postman的使用
    查看>>
    Postman的使用说明
    查看>>
    Postman被低估的功能 — 自动化接口测试
    查看>>
    Postman被低估的功能 — 自动化接口测试
    查看>>
    Postman轻松签名,让SHA256withRSA保驾护航
    查看>>
    Postman还能做Mock?又学了一招!
    查看>>
    Postman还能做Mock?又学了一招!
    查看>>
    postman进行http接口测试
    查看>>
    Postman高阶技能:Collection集合批量运行!
    查看>>
    postMessage跨标签页共享数据
    查看>>
    QImage对一般图像的处理
    查看>>
    post为什么会发送两次请求?
    查看>>
    Post表单提交TextArea的值出现转译乱码问题 - Spring MVC处理表单提交
    查看>>
    Power BI 中的 Python 可视化需要什么设置?任何特定的 matplotlib 包版本或系统设置?
    查看>>
    Power BI:如何在 Power Query 编辑器中将 Python 与多个表一起使用?
    查看>>