protobuf与json转换小结

protobuf与json转换小结是一个比较常见的问题,在这里我将为你提供一个完整的攻略。

什么是protobuf

Protobuf(Protocol Buffers)是Google开发的一种轻便、高效、通用的数据序列化格式,可以用于数据存储、RPC(Remote procedure call)和数据交换等领域。它与XML和JSON等其他序列化格式相比,更为紧凑、快速,而且具有更好的性能。

在使用Protobuf前,需要定义一个.proto文件,该文件定义了要序列化的数据结构和数据类型。在定义好.proto文件的所有内容后,通过利用ProtoBuf中的编译器生成所需的数据对应的代码,进而在代码中调用对应接口进行数据序列化和反序列话操作。

protobuf与json之间的转换

Protobuf和JSON之间的转换非常常见,下面是protobuf和JSON之间转换的两种方式:

第一种方式:使用protobuf自带的JsonFormat工具

protobuf在自己的库中提供了JsonFormat工具,可以在protobuf和JSON之间进行转换,下面是转换的示例:

定义.proto文件

syntax = "proto3";

package tutorial;

message Person {
  string name = 1;
  int32 id = 2;  // Unique ID number for this person.
  string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;
}

生成对应的数据结构

通过proto文件生成对应的数据结构:

protoc --proto_path=. --python_out=. ./person.proto

生成person_pb2.py文件,包含了所有protobuf数据对应的Python类

protobuf数据序列化为JSON字符串

import json
from google.protobuf.json_format import MessageToJson
from tutorial.person_pb2 import Person, PhoneNumber

def protobuf_to_json():
  person = Person()
  person.name = "John Doe"
  person.id = 1234
  person.email = "jdoe@example.com"
  phone = PhoneNumber()
  phone.number = "555-4321"
  phone.type = Person.HOME
  person.phones.append(phone)

  # 将protobuf数据转换为JSON字符串
  json_str = MessageToJson(person)
  print(json_str)

执行代码生成的JSON字符串为:

{
  "name": "John Doe",
  "id": 1234,
  "email": "jdoe@example.com",
  "phones": [
    {
      "number": "555-4321",
      "type": "HOME"
    }
  ]
}

JSON字符串反序列化为protobuf数据

def json_to_protobuf():
  json_str = """
  {
    "name": "John Doe",
    "id": 1234,
    "email": "jdoe@example.com",
    "phones": [
      {
        "number": "555-4321",
        "type": "HOME"
      }
    ]
  }
  """

  # 将JSON字符串转换为protobuf数据
  person = Person()
  json_format.Parse(json_str, person)
  print(person.name, person.id, person.email, person.phones[0].number, person.phones[0].type)

第二种方式:手动转换

不使用protobuf自带的工具,而是使用Python中自带的json库、protobuf库中自带的编码和解码方法手动转换。下面是手动转换的示例:

protobuf数据序列化为JSON字符串

def protobuf_to_json2():
  person = Person()
  person.name = "John Doe"
  person.id = 1234
  person.email = "jdoe@example.com"
  phone = PhoneNumber()
  phone.number = "555-4321"
  phone.type = Person.HOME
  person.phones.append(phone)

  # 手动序列化:protobuf数据转换为Python字典
  person_dict = {
    "name": person.name,
    "id": person.id,
    "email": person.email,
    "phones": [{
      "number": p.number,
      "type": p.type
    } for p in person.phones]
  }

  # 将Python字典转换为JSON字符串
  json_str = json.dumps(person_dict, indent=2)
  print(json_str)

执行代码生成的JSON字符串为:

{
  "name": "John Doe",
  "id": 1234,
  "email": "jdoe@example.com",
  "phones": [
    {
      "number": "555-4321",
      "type": "HOME"
    }
  ]
}

JSON字符串反序列化为protobuf数据

def json_to_protobuf2():
  json_str = """
  {
    "name": "John Doe",
    "id": 1234,
    "email": "jdoe@example.com",
    "phones": [
      {
        "number": "555-4321",
        "type": "HOME"
      }
    ]
  }
  """

  # 将JSON字符串转换为Python字典
  person_dict = json.loads(json_str)

  # 手动反序列化:Python字典转换为protobuf数据
  person = Person()
  person.name = person_dict["name"]
  person.id = person_dict["id"]
  person.email = person_dict["email"]
  for phone_dict in person_dict["phones"]:
    phone = person.phones.add()
    phone.number = phone_dict["number"]
    phone.type = getattr(Person.PhoneType, phone_dict["type"])

  print(person.name, person.id, person.email, person.phones[0].number, person.phones[0].type)

总结

以上就是protobuf和JSON之间转换的两种方式。如果你了解了protobuf文件的定义和Python中使用Protobuf的基本知识,在protobuf和JSON之间进行转换并不会是一件难事。哪个转换方式更好,需要根据实际情况来选择,这里的示例只是展示了两种基本的转换方法,具体的应用需要根据实际情况进行选择。

阅读剩余 76%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:protobuf与json转换小结 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • SpringBoot Pom文件依赖及Starter启动器详细介绍

    SpringBoot Pom文件依赖及Starter启动器详细介绍 在SpringBoot中,我们可以使用Pom文件来管理依赖,并使用Starter启动器来简化依赖的配置。本文将详细讲解SpringBoot Pom文件依赖及Starter启动器详细介绍的完整攻略,并提供两个示例。 1. Pom文件依赖 在SpringBoot中,我们可以使用Pom文件来管理依…

    Java 2023年5月15日
    00
  • Spring MVC整合FreeMarker的示例

    针对Spring MVC整合FreeMarker的示例,我将给出完整的攻略,包含以下内容: 环境准备 配置FreeMarker 编写Controller 编写FreeMarker模板 示例演示 下面我们详细讲解每一项内容。 环境准备 首先需要准备好环境。在本示例中,我们将使用以下环境: JDK 8 Maven 3 Spring 5 FreeMarker 2.…

    Java 2023年5月19日
    00
  • java servlet 几种页面跳转的方法

    Java Servlet 几种页面跳转的方法 在 Java 的 Servlet 编程中,页面跳转是一项至关重要的技能。实现页面的跳转可以使Web服务器更加灵活地管理页面的内容和功能。这里我们介绍几种常见的跳转方式。 重定向(Redirect) 重定向是范围最广,也是最常见的页面跳转方式。它的好处是可以跳转到其他 Web 站点中的任意一个页面,但是缺点是 UR…

    Java 2023年6月15日
    00
  • MyBatis自定义typeHandler的完整实例

    针对“MyBatis自定义typeHandler的完整实例”这个问题,我将会提供一份详细攻略。 什么是 MyBatis TypeHandler? MyBatis 的 TypeHandler 可以实现 Java 数据类型(如 String, Date 等)和 JDBC 对象之间的转换。MyBatis 会自动寻找合适的 TypeHandler 来执行转换,并且你…

    Java 2023年6月15日
    00
  • Java利用位运算实现加减乘除的方法详解

    Java利用位运算实现加减乘除的方法详解 简介 Java位运算是操作二进制数的一种方式,包括位与、位或、位异或、位取反等操作。通过运用位运算的特殊性质,可以实现加减乘除等数学运算。本文将详细讲解Java中如何利用位运算实现加减乘除操作。 加法 位运算中的加法采用异或操作和与操作的组合实现。可以用以下公式表示: a + b = (a ^ b) + ((a &a…

    Java 2023年5月19日
    00
  • jsp中过滤器选择过滤器的写法详解

    首先,过滤器是JSP中非常重要的组件,它可以对请求进行拦截、预处理和后处理。在实际开发中,我们经常需要对请求做一些统一的处理,这时候过滤器就派上用场了。 一、写一个过滤器的基本步骤 在JSP中,编写一个过滤器需要经历以下几个步骤: 1.创建一个 Java 类并实现 javax.servlet.Filter 接口。 2.实现接口中的 doFilter 方法,该…

    Java 2023年6月15日
    00
  • Hibernate基于ThreadLocal管理Session过程解析

    当我们使用Hibernate进行对象关系映射时,我们常常需要处理Session对象的创建、使用和关闭等生命周期的管理。为了确保线程安全和线程隔离,通常采用ThreadLocal变量来管理Session对象。Hibernate基于ThreadLocal管理Session的过程如下: 创建ThreadLocal对象 我们可以使用如下代码创建一个ThreadLoc…

    Java 2023年5月19日
    00
  • Tomcat环境变量如何配置

    Tomcat是一个用于Java应用程序的Web服务器和Servlet容器。在使用Tomcat的过程中,为了保证Web应用程序的正常运行,需要正确地配置Tomcat环境变量。下面是配置Tomcat环境变量的完整攻略: 1. 下载和安装Tomcat 在开始配置Tomcat环境变量之前,我们首先需要下载和安装Tomcat。Tomcat的下载地址为:https://…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部