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腳本就為你干這事提供了溫床
,下面會介紹這個過程:
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的問題了
。
如果測試腳本用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()
#python testjson2pb.py
是不是很簡單啊,自從有了這個腳本,再用不用擔心人肉從json生成protobuf的問題了
。
原文鏈接:
http://blog.chinaunix.net/uid-27714502-id-4067350.html
