protobuf对象与JSON相互转换

news2024/11/19 19:36:47

除了之前的 protobuf-java依赖之外,还需要引入 protobuf-java-uti 依赖:

        <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.19.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java-util -->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <version>3.19.1</version>
        </dependency>

如果不使用protobuf提供的JSON API,而使用fastJson等,直接序列化 com.google.protobuf.Message proto对象,会报错。如果希望使用第三方的JSON API,可以重新定义一个实体类,抽取需要的字段。

一、注意默认值

官网文档:https://protobuf.dev/programming-guides/proto3/#default

在这里插入图片描述

官方字段默认值,使用时需要注意:

  1. 对于标量消息字段,一旦解析了消息,就无法判断字段是显式设置为默认值还是根本没有设置(例如布尔值是否设置为false):所以,在定义消息类型时应该记住这一点。例如,如果你不希望某些行为在默认情况下也发生,不要使用布尔值在设置为false时打开某些行为。
  2. 如果将标量消息字段设置为其默认值(显式设置),则该值将不会在网络上序列化。
  3. Json 转 proto 对象时,如果Json字符串中的设置为了默认值(显式设置),则该值将不会在网络上序列化。

1、protobuf对象 转 JSON串

// 接收数据反序列化:将字节数据转化为对象数据。
UserProtoBuf.User user = UserProtoBuf.User.parseFrom(byteData);

// 1、proto 对象 转 Json
//获取 Printer对象用于生成JSON字符串
JsonFormat.Printer printer = JsonFormat.printer();
String userJsonStr = printer.print(user);

Printer对象生成 JSON字符串时,支持设置一些功能方法。比如:

  • includingDefaultValueFields():表示 Json输出包含默认值(显示和隐式赋默认值)的字段。
  • preservingProtoFieldNames():表示使用.proto文件中定义的原始proto字段名而不是将其转换为lowerCamelCase输出。默认 lowerCamelCase的输出。

2、JSON串 转 protobuf对象

// 创建 proto 对象
UserProtoBuf.User.Builder userBuilder = UserProtoBuf.User.newBuilder();

// 2、Json 转 proto 对象
//获取 Parser对象用于解析JSON字符串
JsonFormat.Parser parser = JsonFormat.parser();
parser.merge(userJsonStr2, userBuilder);

Parser对象解析 JSON字符串时,支持设置一些功能方法。比如:

  • ignoringUnknownFields():表示如果 json 串中存在的属性,proto 对象中不存在,则进行忽略,否则会抛出 InvalidProtocolBufferException异常。

二、示例实战

proto文件内容如下:

syntax = "proto3";

//生成 proto java文件名(一般指定,文件名+自定义。如果不指定,默认时文件名+OuterClass)
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;

}

1、使用 JsonFormat默认功能

import com.google.protobuf.util.JsonFormat;

public class UserTest {

    public static void main(String[] args) throws Exception {

        // 将数据序列化
        byte[] byteData = getClientPush();
        System.out.println("获取到字节数据:byteData长度=" + byteData.length);
        System.out.println("===========");

        /**
         * 接收数据反序列化:将字节数据转化为对象数据。
         */
        UserProtoBuf.User user = UserProtoBuf.User.parseFrom(byteData);
        System.out.println("==== get获取 user信息:=======");
        System.out.println("user信息:     \n" + user);
        System.out.println("------------------");
        System.out.println("getAge=         " + user.getAge());
        System.out.println("getTimestamp=   " + user.getTimestamp());
        System.out.println("getEnabled=     " + user.getEnabled());
        System.out.println("getHeight=      " + user.getHeight());
        System.out.println("getWeight=      " + user.getWeight());
        System.out.println("getUserName=        " + user.getUserName());
        System.out.println("getFullAddress= " + user.getFullAddress());


        /**
         * proto 对象 转 Json互转
         */
        // 1、proto 对象 转 Json
        String userJsonStr = JsonFormat.printer()
                //.includingDefaultValueFields() // 表示 Json输出包含默认值(显示和隐式赋默认值)的字段。
                .print(user);
        System.out.println("=====1、proto对象 转 Json字符串:======");
        System.out.println("userJsonStr=    " + userJsonStr);

        // 2、Json 转 proto 对象
        String userJsonStr2 = "{\n" +
                "    \"age\":18,\n" +
                "    \"timestamp\":\"1698377283315\",\n" +
                "    \"enabled\":false,\n" +
                "    \"height\":1.8,\n" +
                "    \"weight\":66.76,\n" +
                "    \"userName\":\"赵云\"\n" +
                "}";
        // 创建 proto 对象
        UserProtoBuf.User.Builder userBuilder = UserProtoBuf.User.newBuilder();
        JsonFormat.parser()
                //.ignoringUnknownFields() // 表示如果 json 串中存在的属性,proto 对象中不存在,则进行忽略,否则会抛出 InvalidProtocolBufferException异常
                .merge(userJsonStr2, userBuilder);

        UserProtoBuf.User user1 = userBuilder.build();
        System.out.println("=====2、Json 转 proto 对象:======");
        System.out.println("user1信息:        \n" + user1);
        System.out.println("------------------");
    }

    /**
     * 模拟发送方,将数据序列化后发送
     *
     * @return
     */
    private static byte[] getClientPush() {
        // 按照定义的数据结构,创建一个对象。
        UserProtoBuf.User.Builder user = UserProtoBuf.User.newBuilder();
        user.setAge(18);
        user.setTimestamp(System.currentTimeMillis());
        user.setEnabled(false);
        //user.setEnabled(true);
        //user.setHeight(1.88F);
        user.setWeight(66.76D);
        user.setUserName("赵云");
        //user.setFullAddress("王者-打野");

        /**
         * 发送数据序列化:将对象数据转化为字节数据输出
         */
        UserProtoBuf.User userBuild = user.build();
        byte[] bytes = userBuild.toByteArray();
        return bytes;
    }

}

在这里插入图片描述

2、设置 JsonFormat处理功能

这里使用 JsonFormat的这两个方法。其他方法自行查看。

  • Printer对象使用 includingDefaultValueFields()方法。
  • Parser对象使用 ignoringUnknownFields()方法。

将上面这两个方法的注释打开,运行结果如下:

在这里插入图片描述

– 求知若饥,虚心若愚。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1141676.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux可视化运维工具

今天推荐两个linux可视化的运维工具Cockpit和orion-ops Cockpit Cockpit是CentOS 8默认内置的一个基于Web的可视化管理工具。它提供了对一系列常见命令行管理操作的图形化支持&#xff0c;包括用户管理、防火墙管理、服务器资源监控等等。方便易用的Cockpit号称是适用于所有人…

一文解决:Swagger API 未授权访问漏洞问题

Swagger 是一个用于设计、构建、文档化和使用 RESTful 风格的 Web 服务的开源软件框架。它通过提供一个交互式文档页面&#xff0c;让开发者可以更方便地查看和测试 API 接口。然而&#xff0c;在一些情况下&#xff0c;未经授权的访问可能会导致安全漏洞。本文将介绍如何解决 …

基于SpringBoot + Vue的学生成绩管理系统的设计与实现源码及搭建视频

基于SpringBoot Vue的学生成绩管理系统的设计与实现 引言 1.1目的 该文档的目的是描述学生成绩管理系统的概要设计&#xff0c;主要内容包括系统功能简介、系统结构设计、模块设计和界面设计等。 本文档的预期读者包括&#xff1a;产品设计者、编程人员、系统用户。 1.2 范围…

高品质工地建筑模板,防水耐用,易脱模

欢迎选购我们的产品&#xff1a;高品质工地建筑模板。作为一家专业厂家&#xff0c;我们提供适用于高层建筑的建筑模板&#xff0c;具有出色的防水耐用性能&#xff0c;且不易开胶。1. 高品质工地建筑模板&#xff1a;我们的建筑模板经过精心设计和制作&#xff0c;以确保其高品…

Python 中多态性的示例和类的继承多态性

单词 “多态” 意味着 “多种形式”&#xff0c;在编程中&#xff0c;它指的是具有相同名称的方法/函数/操作符&#xff0c;可以在许多不同的对象或类上执行。 函数多态性 一个示例是 Python 中的 len() 函数&#xff0c;它可以用于不同的对象。 字符串 对于字符串&#xf…

新的iLeakage攻击从Apple Safari窃取电子邮件和密码

图片 导语&#xff1a;学术研究人员开发出一种新的推测性侧信道攻击&#xff0c;名为iLeakage&#xff0c;可在所有最新的Apple设备上运行&#xff0c;并从Safari浏览器中提取敏感信息。 攻击概述 iLeakage是一种新型的推测性执行攻击&#xff0c;针对的是Apple Silicon CPU和…

LabVIEW更改图像特定部分的颜色

LabVIEW更改图像特定部分的颜色 在随附的照片中&#xff0c;想将包围的部分更改为黄色。该怎么做&#xff1f;或者如何将图像的蓝色部分更改为绿色。 绘制拼合像素图不接受数组或输出数组。如果需要有关函数的更多信息&#xff0c;请按 CTRL H 打开上下文帮助&#xff0c;或单…

linux shell脚本修改ini配置文件[session]下的键值

比如我要修改一个配置文件&#xff0c;如下&#xff0c;修改systemFlag.ini下的[huake]下的ip和port的值 代码如下&#xff0c;我就不解释了&#xff0c;有注释&#xff0c;用的是sed 来修改的&#xff0c;不懂的&#xff0c;可以去学习一下 #!/bin/bash #获取当前路径 curr…

无需更换vue-cli 脚手架 uniapp-搭建项目-H5-低版本安卓IOS兼容问题(白屏)(接口请求异常)

✨求关注~ &#x1f4bb;博客&#xff1a;www.protaos.com I. 简介 A. UniApp项目概述 B. 白屏和接口请求异常问题的背景 II. 白屏问题 A. 问题描述 1、uniapp 打包H5内嵌入APP内、低版本手机系统访问白屏问题 B. 问题根本原因 1、低版本手机系统 自带的webview内核不支持ES6语…

开放式耳机推荐百元价位、好用的开放式耳机推荐

个人很喜欢体验新潮或者与众不同的耳机&#xff0c;这不就发现了不一样的开放式耳机&#xff0c;这种耳机不需要插入耳道&#xff0c;而是采用开放式设计&#xff0c;最大的优点是在听音乐的同时能够感知周围环境的声音效果&#xff0c;同时佩戴也非常舒适&#xff0c;因此深受…

计算机操作系统重点概念整理-第四章 内存管理【期末复习|考研复习】

第四章 内存管理 【期末复习|考研复习】 计算机操作系统系列文章传送门&#xff1a; 第一章 计算机系统概述 第二章 进程管理 第三章 进程同步 第四章 内存管理 第五章 文件管理 第六章 输出输出I/O管理 文章目录 第四章 内存管理 【期末复习|考研复习】前言四、内存管理4.1 内…

centos ubantu IP一直变化,远程连接不上问题

文章目录 一、为什么IP地址会变1.主机DHCP导致 二、解决IP地址变化1.centos2.ubantu 总结 虚拟机能连接为互联网,但下一次启动IP地址再发生变化,无法使用ssh远程连接 一、为什么IP地址会变 1.主机DHCP导致 虚拟机系统(ubantu,centos…)启动后会向本地申请IP地址租约,租聘的I…

[Docker]三.Docker 部署nginx,以及映射端口,挂载数据卷

一.Docker 部署 Nginx 以及端口映射 Docker 部署 Nginx,首先需要下载nginx镜像,然后启动这个镜像,就运行了一个nginx的容器了 1.下载 nginx 镜像并启动容器 #查看是否存在nginx镜像:发现没有nginx镜像 [rootlocalhost zph]# docker images | grep nginx#下载nginx镜像 [rootl…

高等数学教材重难点题型总结(六)定积分的应用

本章全是物理题&#xff0c;总的来说计算层面并不难&#xff0c;难点主要在于&#xff1a;对于体积和面积的题&#xff0c;核心在于抽象出面积/体积元素——本质上就是被积函数&#xff1b;对于物理题&#xff0c;基础的物理的公式一定要牢记~ 1.求平面面积 2.求旋转体的体积…

【DOCKER】

Docker 出现&#xff1a; 解决了运行环境和配置问题的软件容器。 方便做持续集成并有助于整体发布的容器虚拟化技术。 面试题&#xff1a; 容器和虚拟机比较&#xff1f; 区别&#xff1a; 1.Docker的三件套 1.镜像&#xff1a; 2.容器 3.仓库 2. 基础架构图 2.…

Kafka - 3.x Producer 生产者最佳实践

文章目录 生产经验_生产者提高吞吐量核心参数Code 生产经验_数据可靠性消息的发送流程ACK应答机制ack应答级别应答机制 小结Code 生产经验_数据去重数据传递语义幂等性幂等性原理开启幂等性配置&#xff08;默认开启&#xff09; 生产者事务kafka事务原理事务代码流程 生产经验…

Leetcode—121.买卖股票的最佳时机【简单】

2023每日刷题&#xff08;十一&#xff09; Leetcode—17.电话号码的字母组合 枚举法题解 参考自灵茶山艾府 枚举法实现代码 int maxProfit(int* prices, int pricesSize){int i;int max 0;int minPrice prices[0];for(i 1; i < pricesSize; i) {int tmp prices[i] -…

拼多多根据ID取商品详情 API 返回值说明

item_get-根据ID取商品详情 pinduoduo.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;获取key和secret接入secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_sea…

Small Tip: 如何实现从Eclipse里面直接跳转到Analysis for Office

查看ADSO或者CP的数据时&#xff0c;一般情况下&#xff0c;预览只能有这两个选项。 可以扩展成以下这样&#xff1a; 方法&#xff1a; SPRO-> 选参数&#xff0c;填文本。然后重启Eclipse.

Web:探索 SpreadJS强大的在线电子表格库

1、概述 SpreadJS 是葡萄城结合 40 余年专业控件技术和在电子表格应用领域的经验而推出的纯前端表格控件,基于 HTML5,兼容 450 多种 Excel 公式,具备“高性能、跨平台、与 Excel 高度兼容”的产品特性,SpreadJS 在界面和功能上与 Excel 高度类似,但又不局限于 Excel,而是…