protobuf与json互相转换
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
如果测试脚本用Python来写的话,一般的做法是用的Python调用json模块中函数解析json文件,然后新建protobuf对象,依次填写各字段,然后发送出去。
当然如果愿意造上面的轮子也没关系,如果想偷懒也是可行的,pbjson.py脚本就为你干这事提供了温床
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

是不是很简单啊,自从有了这个脚本,再用不用担心人肉从json生成protobuf的问题了
。
protobuf与json互相转换的更多相关文章
- protobuf与json转换
protobuf对象不能直接使用jsonlib去转,因为protobuf生成的对象的get方法返回的类型有byte[],而只有String类型可以作为json的key,protobuf提供方法进行转换 ...
- protobuf转json
方法介绍 protobuf的介绍在这里就不详细介绍了,主要是俺也是刚接触,感兴趣的同学可以去搜索相关博客或者直接去看源码以及google的官方文档(官方文档表示很吃力)或者去这个网站:https:// ...
- protobuf与json相互转换的方法
google的protobuf对象转json,不能直接使用FastJson之类的工具进行转换,原因是protobuf生成对象的get方法,返回的类型有byte[],而只有String类型可以作为jso ...
- json日期转换
//调用 ChangeDateFormat(CreatTime) //json日期转换 function ChangeDateFormat(jsondate) { jsondate = jsondat ...
- java中Array/List/Map/Object与Json互相转换详解
http://blog.csdn.net/xiaomu709421487/article/details/51456705 JSON(JavaScript Object Notation): 是一种轻 ...
- Json格式转换
验证Json格式可以进入 http://json.cn/ json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构1.对象:对象 ...
- JSON.stringify转换Date不正确的解決方法
JSON.stringify转换Date不正确的原因:国际时区(UTC)和中国时区(GMT)的原因,东八区+8等于国际时区. 解决方法,重新Es5的Date.prototype.toJSON方法,代码 ...
- 使用js进行string和json之间转换的方法
在数据传输过种中,json是以文本,即字符串的形式传递,字符串形似Json对象: var str1 = '{ "name": "Amy", "sex& ...
- 前台 JSON对象转换成字符串 相互转换 的几种方式
在最近的工作中,使用到JSON进行数据的传递,特别是从前端传递到后台,前台可以直接采用ajax的data函数,按json格式传递,后台Request即可,但有的时候,需要传递多个参数,后台使用requ ...
随机推荐
- #ifdef,#else,#endif,#if 拾忆
预处理就是在进行编译的第一遍词法扫描和语法分析之前所作的工作.说白了,就是对源文件进行编译前,先对预处理部分进行处理,然后对处理后的代码进行编译.这样做的好处是,经过处理后的代码,将会变的很精短. ...
- iosiOSlabel基本使用以及文字自适应
(如果需要的不是使用的属性值如换行形式,可以把对应的属性在程序中书写然后按"command"+鼠标左键点击就可以查看所有属性值) 一label基本设置 self.view.back ...
- linux中将程序加入到开机自动启动
如果将在linux中将命令或者程序设置为开机自动启动,只需要进入到将对应命令加入到/etc/rc.d/rc.local文件里即可,如下 打开文件,vi /etc/rc.d/rc.local #!/bi ...
- hdu_5792_World is Exploding(树状数组+逆序对)
题目链接:hdu_5792_World is Exploding 题意: 给你一个数列,让你找有多少个(a,b,c,d)满足a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab ...
- poj_2778_DNA Sequence(AC自动机+矩阵)
题目链接:poj_2778_DNA Sequence 题意: 有m个模式串,然后给你一个长度n,问你n长度的DNA序列有多少种不包含这m个模式串 题解: 这题显然要用AC自动机,将模式串的AC自动机建 ...
- hdu_5695_Gym Class(拓扑排序)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5695 题意:中文题,不解释 题解:逆向拓扑字典序就行 #include<cstdio> # ...
- 两台linux利用heartbeat+drbd 完美实现双机热备
一直想做基于linux的双机热备,一直没有时间和机会.一直以为只要做双机热备的实验就必须两台机器外接一个存储.甚至一个月以前在学习keepalived的时候还在琢磨keepalvied去掉哪些条件可以 ...
- network: 思科-华为光模块
思科-华为光模块的分类比较 摘要:本文介绍:思科GLC-SX-MM,GLC-LH-SM光模块等产品参数与图片,华为光模块的型号与分类等知识. 光模块分类与介绍 一.思科厂家 1.多模光模块 型号: ...
- java中的类修饰符、成员变量修饰符、方法修饰符
类修饰符: public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类. abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现. fi ...
- 【dfs 回溯】 zoj 1004
题意:给出一个源字符串和一个目标字符串,打出所有符合stack操作的i,o串使得对于源字符串的操作能变为目标字符串 思路:搜索,回溯. 之前想过是不是队列,觉得不对那样bfs是求最优解了:也想过用结构 ...