将protobuf Any类型转换为JSON时,如何排除@type字段?
如何移除Protobuf Any类型转JSON时的@type字段
有三种可行方案可以实现需求:
方案一:解析回原始消息后再序列化
既然Any类型是对原始Cluster消息的包装,直接把Any解析回Cluster实例,再序列化就能得到不带@type的JSON:
cluster := &pb.Cluster{Name: "123"} c, err := anypb.New(cluster) if err != nil { log.Fatal(err) } // 将Any解析回原始Cluster类型 target := &pb.Cluster{} err = c.UnmarshalTo(target) if err != nil { log.Fatal(err) } // 序列化原始消息 jsonBytes, err := protojson.Marshal(target) if err != nil { log.Fatal(err) } log.Println(string(jsonBytes))
运行后会输出:{"name":"123"}
方案二:直接序列化Any的Value字段
Any类型内部的Value字段就是原始消息的二进制形式,可以直接用protojson序列化这个字段:
cluster := &pb.Cluster{Name: "123"} c, err := anypb.New(cluster) if err != nil { log.Fatal(err) } // 直接序列化Any的Value字段 jsonBytes, err := protojson.Marshal(c.Value) if err != nil { log.Fatal(err) } log.Println(string(jsonBytes))
这个方法跳过了Any的包装层,直接处理原始消息的二进制数据,结果同样符合需求。
方案三:手动修改JSON结果(不推荐)
如果不想依赖Protobuf的解析逻辑,可以先序列化Any得到带@type的JSON,再转成map删除对应字段后重新序列化:
cluster := &pb.Cluster{Name: "123"} c, err := anypb.New(cluster) if err != nil { log.Fatal(err) } jsonBytes, err := protojson.Marshal(c) if err != nil { log.Fatal(err) } // 转成map删除@type字段 var data map[string]interface{} err = json.Unmarshal(jsonBytes, &data) if err != nil { log.Fatal(err) } delete(data, "@type") // 重新序列化 resultBytes, err := json.Marshal(data) if err != nil { log.Fatal(err) } log.Println(string(resultBytes))
这个方法虽然能实现,但需要额外的JSON解析和序列化步骤,性能不如前两种,仅适合临时场景。
内容的提问来源于stack exchange,提问作者Algorithm
相关产品推荐
相关产品推荐

