golang json转proto(protocol buffer)

golang json转proto(protocol buffer),第1张

golang json转proto(protocol buffer)

json数据传输格式在现在前后端开发很常用,微服务开发现在也很流行,使用golang开发微服务使用的是google的GRPC框架,数据传输采用protocolbuffer,通常前端数据使用json,而经过后端微服务传输使用proto,这时如果采用直接赋值方式,当数据量大了就要写很多赋值语句。那么能不项json和xml直接序列化和反序列化方式转换呢?答案是有的!
protocol buffer官方提供了一个包github.com/golang/protobuf/jsonpb
这个包里面有个json_test.go文件,可以参考如何转换
参考其中一个函数

func TestUnmarshalUnsetRequiredFields(t *testing.T) {
	tests := []struct {
		desc string
		pb   proto.Message
		json string
	}{
		{
			desc: "direct required field missing",
			pb:   &pb2.MsgWithRequired{},
			json: `{}`,
		},
		{
			desc: "direct required field set to null",
			pb:   &pb2.MsgWithRequired{},
			json: `{"str": null}`,
		},
		{
			desc: "indirect required field missing",
			pb:   &pb2.MsgWithIndirectRequired{},
			json: `{"subm": {}}`,
		},
		{
			desc: "indirect required field set to null",
			pb:   &pb2.MsgWithIndirectRequired{},
			json: `{"subm": {"str": null}}`,
		},
		{
			desc: "direct required bytes field missing",
			pb:   &pb2.MsgWithRequiredBytes{},
			json: `{}`,
		},
		{
			desc: "direct required bytes field set to null",
			pb:   &pb2.MsgWithRequiredBytes{},
			json: `{"byts": null}`,
		},
		{
			desc: "direct required wkt field missing",
			pb:   &pb2.MsgWithRequiredWKT{},
			json: `{}`,
		},
		{
			desc: "direct required wkt field set to null",
			pb:   &pb2.MsgWithRequiredWKT{},
			json: `{"str": null}`,
		},
		{
			desc: "any containing message with required field set to null",
			pb:   &pb2.KnownTypes{},
			json: `{"an": {"@type": "example.com/jsonpb.MsgWithRequired", "str": null}}`,
		},
		{
			desc: "any containing message with missing required field",
			pb:   &pb2.KnownTypes{},
			json: `{"an": {"@type": "example.com/jsonpb.MsgWithRequired"}}`,
		},
		{
			desc: "missing required in map value",
			pb:   &pb2.MsgWithIndirectRequired{},
			json: `{"map_field": {"a": {}, "b": {"str": "hi"}}}`,
		},
		{
			desc: "required in map value set to null",
			pb:   &pb2.MsgWithIndirectRequired{},
			json: `{"map_field": {"a": {"str": "hello"}, "b": {"str": null}}}`,
		},
		{
			desc: "missing required in slice item",
			pb:   &pb2.MsgWithIndirectRequired{},
			json: `{"slice_field": [{}, {"str": "hi"}]}`,
		},
		{
			desc: "required in slice item set to null",
			pb:   &pb2.MsgWithIndirectRequired{},
			json: `{"slice_field": [{"str": "hello"}, {"str": null}]}`,
		},
		{
			desc: "required inside oneof missing",
			pb:   &pb2.MsgWithOneof{},
			json: `{"msgWithRequired": {}}`,
		},
		{
			desc: "required inside oneof set to null",
			pb:   &pb2.MsgWithOneof{},
			json: `{"msgWithRequired": {"str": null}}`,
		},
		{
			desc: "required field in extension missing",
			pb:   &pb2.Real{},
			json: `{"[jsonpb.extm]":{}}`,
		},
		{
			desc: "required field in extension set to null",
			pb:   &pb2.Real{},
			json: `{"[jsonpb.extm]":{"str": null}}`,
		},
	}

	for _, tc := range tests {
		if err := UnmarshalString(tc.json, tc.pb); err == nil {
			t.Errorf("%s: expected error while unmarshaling with unset required fields %s", tc.desc, tc.json)
		}
	}
}

上面的代码比较多,我们可以来做个简单点的做个实验

1、首先新建一个工程,在工程目录下新建一个文件夹myproto用来存放proto文件,编写proto文件my.proto

syntax = "proto3";
option go_package ="./myproto";#加这一行主要是方便编译后的文件存放到这个目录下


message Message {
	string say = 1;
}

2、然后编译proto文件生成my.pb.go,

命令:protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/addressbook.proto

官方文档:https://developers.google.cn/protocol-buffers/docs/gotutorial
其中一段是:

type Message struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Say string `protobuf:"bytes,1,opt,name=say,proto3" json:"say,omitempty"`
}

看到json:"say,omitempty"这个标签是不是很熟悉!

3、到main.go文件编写测试代码

import (
"Test/myproto"
"github.com/golang/protobuf/jsonpb"
"fmt"
)
func Test() {

	jsonstr := `{"say":"Tom"}`
	pb := &myproto.Message{}
	if err := jsonpb.UnmarshalString(jsonstr, pb); err == nil {
		fmt.Errorf("err:%s\n", err)
	}
	fmt.Printf("pb.say:%s\n", pb.Say)
}

func main(){
Test()
}

至此测试实验完毕!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/993937.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存