doupaxia2478 2018-04-05 13:15 采纳率: 100%
浏览 47
已采纳

马歇尔/解组JSONPB

I am trying to Unmarshal some json data to a proto message.

JSON

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

Proto

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"`
}

How can I map the above JSON to my proto Message (from what I can see there is no way to specify tags in proto atm)?

  • 写回答

1条回答 默认 最新

  • dongyin8991 2018-04-05 15:37
    关注

    Your JSON document doesn't match the proto definition; name != first_name and numbers != phone_numbers.

    You can define another type that has the same fields as Item but different struct tags and then convert to 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)
    

    If every JSON document you want to decode has this structure, it may be more convenient to let Item implement 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
    ", i)
    }
    

    Try it on the playground: https://play.golang.org/p/0qibavRJbwi

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog