Marshall/Unmarshal JSONPB

Marshall/Unmarshal JSONPB

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

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

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

您的 JSON 文档与原型定义不匹配;名称 != first_name 和数字 != 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