时间: 2020-11-22|55次围观|0 条评论

Java

http://code.google.com/p/protobuf-java-format/

maven

<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.2</version>
</dependency>

从protobuf转json

Message someProto =SomeProto.getDefaultInstance();
String jsonFormat =JsonFormat.printToString(someProto);

从json转protobuf

Message.Builder builder =SomeProto.newBuilder();
String jsonFormat = _load json document from a source_;
JsonFormat.merge(jsonFormat, builder);

C++

https://github.com/shramov/json2pb

 

Python

https://github.com/NextTuesday/py-pb-converters

导入模块pbjson.py即可使用。

ps. 原始模块的pb2json函数会自动过滤protobuf中字段值为空的数据。根据需要可注释掉过滤代码。

 pbjson .py:

import simplejson
  from google.protobuf.descriptor import FieldDescriptor as FD
   
  class ConvertException(Exception):
  pass
   
  def dict2pb(cls, adict, strict=False):
  """
  Takes a class representing the ProtoBuf Message and fills it with data from
  the dict.
  """
  obj = cls()
  for field in obj.DESCRIPTOR.fields:
  if not field.label == field.LABEL_REQUIRED:
  continue
  if not field.has_default_value:
  continue
  if not field.name in adict:
  raise ConvertException('Field "%s" missing from descriptor dictionary.'
  % field.name)
  field_names = set([field.name for field in obj.DESCRIPTOR.fields])
  if strict:
  for key in adict.keys():
  if key not in field_names:
  raise ConvertException(
  'Key "%s" can not be mapped to field in %s class.'
  % (key, type(obj)))
  for field in obj.DESCRIPTOR.fields:
  if not field.name in adict:
  continue
  msg_type = field.message_type
  if field.label == FD.LABEL_REPEATED:
  if field.type == FD.TYPE_MESSAGE:
  for sub_dict in adict[field.name]:
  item = getattr(obj, field.name).add()
  item.CopyFrom(dict2pb(msg_type._concrete_class, sub_dict))
  else:
  map(getattr(obj, field.name).append, adict[field.name])
  else:
  if field.type == FD.TYPE_MESSAGE:
  value = dict2pb(msg_type._concrete_class, adict[field.name])
  getattr(obj, field.name).CopyFrom(value)
  else:
  setattr(obj, field.name, adict[field.name])
  return obj
   
   
  def pb2dict(obj):
  """
  Takes a ProtoBuf Message obj and convertes it to a dict.
  """
  adict = {}
  if not obj.IsInitialized():
  return None
  for field in obj.DESCRIPTOR.fields:
  if not getattr(obj, field.name):
  continue
  if not field.label == FD.LABEL_REPEATED:
  if not field.type == FD.TYPE_MESSAGE:
  adict[field.name] = getattr(obj, field.name)
  else:
  value = pb2dict(getattr(obj, field.name))
  if value:
  adict[field.name] = value
  else:
  if field.type == FD.TYPE_MESSAGE:
  adict[field.name] = \
  [pb2dict(v) for v in getattr(obj, field.name)]
  else:
  adict[field.name] = [v for v in getattr(obj, field.name)]
  return adict
   
   
  def json2pb(cls, json, strict=False):
  """
  Takes a class representing the Protobuf Message and fills it with data from
  the json string.
  """
  return dict2pb(cls, simplejson.loads(json), strict)
   
   
  def pb2json(obj):
  """
  Takes a ProtoBuf Message obj and convertes it to a json string.
  """
  return simplejson.dumps(pb2dict(obj), sort_keys=True, indent=4)

json2pb   

 在功能测试或集成测试中,用json造输入数据,然后moc测试脚本将json转化为protobuf发送给被测试模块或服务,是非常常见的功能测试手段。

        如果测试脚本用Python来写的话,一般的做法是用的Python调用json模块中函数解析json文件,然后新建protobuf对象,依次填写各字段,然后发送出去。

        当然如果愿意造上面的轮子也没关系,如果想偷懒也是可行的,
pbjson.py脚本就为你干这事提供了温床
protobuf与json互相转换插图,下面会介绍这个过程:


1、造json文件,内容如下:

        #vi testjson2pb.json

        {

            "name":"scq",

            "age":30,

            "work_unit":"taobao",

            "class_mate":[

                {

                    "name":"jim",

                    "age":30

                }

            ]

        }

2、造protobuf文件,内容如下:

        #vi testjson2pb.proto

        //class mate

        package json2pb;

        message PersonInfo {

            //my name

            required string name = 1;

            //my age

            optional int32 age = 2;

            //my work unit

            optional string work_unit = 3;

            message ClassMate {

                //name

                optional string name = 1;

                //age

                optional uint32 age = 2;

            }

            repeated ClassMate class_mate = 4;

        }

3、生成protobuf对应python文件:

        #protoc -I=. --python_out=. testjson2pb.proto

        testjson2pb_pb2.py

4、编写测试例子,具体如下:

        #vi testjson2pb.py

        -------------------------------------------------------------------------------------------------

        #!/usr/bin/env python

        # coding=utf-8

        import sys

        import logging

        import os

        import time

        import string

        import pbjson

        import simplejson

        import testjson2pb_pb2

        def main():

            f = file("testjson2pb.json")

            s = simplejson.load(f)

            f.close

            t = pbjson.dict2pb(testjson2pb_pb2.PersonInfo, s)

            print t

        if __name__  ==  "__main__":

            main()

5、执行脚本,结果如下:

        #python testjson2pb.py

        
protobuf与json互相转换插图1

        是不是很简单啊,自从有了这个脚本,再用不用担心人肉从json生成protobuf的问题了
protobuf与json互相转换插图2

        

      

原文链接:
http://blog.chinaunix.net/uid-27714502-id-4067350.html

转载于:https://www.cnblogs.com/catkins/p/5270413.html

原文链接:https://blog.csdn.net/weixin_30342827/article/details/95318202

本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《protobuf与json互相转换
   

还没有人抢沙发呢~