【问题标题】:Marshall/Unmarshal JSONPBMarshall/Unmarshal JSONPB
【发布时间】:2018-04-05 13:15:50
【问题描述】:

我正在尝试将一些 json 数据解组为原始消息。

JSON

   {
        "id": 1,
        "first_name": "name",
        "phone_numbers": []
    }

原型

message Item {
  uint32 id=1;
  string name=2;
  repeated string numbers=3;
}

Proto.go

type Item struct {
    Id    uint32   `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
    Name   string   `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
    Numbers   []string `protobuf:"bytes,4,rep,name=numbers" json:"numbers,omitempty"`
}

如何将上述 JSON 映射到我的 proto 消息(据我所知,无法在 proto atm 中指定标签)?

【问题讨论】:

    标签: go proto


    【解决方案1】:

    您的 JSON 文档与 proto 定义不匹配; name != first_name 和 numbers != phone_numbers。

    你可以定义另一种与Item具有相同字段但结构标签不同的类型,然后转换为Item:

        var x struct {
                Id      uint32   `json:"id,omitempty"`
                Name    string   `json:"first_name,omitempty"`
                Numbers []string `json:"phone_numbers,omitempty"`
        }
    
        if err := json.Unmarshal(jsonDoc, &x); err != nil {
                log.Fatal(err)
        }
    
        var i = Item(x)
    

    如果每一个你要解码的JSON文档都有这个结构,让Item实现json.Unmarshaler可能会更方便:

    package main
    
    import (
            "encoding/json"
            "fmt"
            "log"
    )
    
    var jsonDoc = []byte(`
    {
      "id": 1,
      "first_name": "name",
      "phone_numbers": [
        "555"
      ]
    }
    `)
    
    type Item struct {
            Id      uint32   `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
            Name    string   `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
            Numbers []string `protobuf:"bytes,4,rep,name=numbers" json:"numbers,omitempty"`
    }
    
    // You can define this function is item_json.go or so, then it 
    // isn't removed if you re-generate your types.
    func (i *Item) UnmarshalJSON(b []byte) error {
            type item struct {
                    Id      uint32   `json:"id,omitempty"`
                    Name    string   `json:"first_name,omitempty"`
                    Numbers []string `json:"phone_numbers,omitempty"`
            }
    
            var x item
            if err := json.Unmarshal(jsonDoc, &x); err != nil {
                    return err
            }
    
            *i = Item(x)
    
            return nil
    }
    
    func main() {
            var i Item
            if err := json.Unmarshal(jsonDoc, &i); err != nil {
                    log.Fatal(err)
            }
    
            fmt.Printf("%#v\n", i)
    }
    

    在操场上试试看:https://play.golang.org/p/0qibavRJbwi

    【讨论】:

      猜你喜欢
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多