根据密钥解组JSON

时间:2019-01-25 10:57:55

标签: json go unmarshalling

我正在从网络上接收JSON格式的数据,我需要根据密钥将其解组。
这是数据示例:

{
  "foo": {
    "11883920": {
      "fieldA": 123,
      "fieldB": [
        {
          "fieldC": "a",
          "fieldD": 1173653.22
        }
      ]
    }
  },
  "bar": {
     "123": {
       "fieldE": 123
     }
   }
  "anyOtherkey": {...}
}

逻辑是,如果密钥为foo,它将被取消编组为fooStruct,如果密钥为bar,则将其编为barStruct。 实现此逻辑的最佳方法是什么? (我不想将其解组到map[string]interface{},也许可以使用json.NewDecoder()函数,但是我无法获得预期的结果。)

1 个答案:

答案 0 :(得分:4)

只需创建一个同时包含两个字段的类型:

type MyType struct {
    Foo      *fooStruct `json:"foo,omitempty"`
    Bar      *barStruct `json:"bar,omitempty"`
    OtherKey string     `json:"other_key"`
}

将JSON解组为该类型,只需检查ig Foo和或Bar是否为零即可知道您正在使用什么数据。

这里是操场Demo

其实质是:

type Foo struct {
    Field int `json:"field1"`
}

type Bar struct {
    Message string `json:"field2"`
}

type Payload struct {
    Foo   *Foo   `json:"foo,omitempty"`
    Bar   *Bar   `json:"bar,omitempty"`
    Other string `json:"another_field"`
}

FooBar字段是指针类型,因为值字段会使确定实际设置的字段变得更加麻烦。 omitempty位使您可以封送相同类型以重新创建原始有效负载,因为nil值将不会显示在输出中。

要检查在原始JSON字符串中设置了哪个字段,只需编写:

var data Payload
if err := json.Unmarshal([]byte(jsonString), &data); err != nil {
    // handle error
}
if data.Foo == nil && data.Bar == nil {
    // this is probably an error-case you need to handle
}
if data.Foo == nil {
    fmt.Println("Bar was set")
} else {
    fmt.Println("Foo was set")
}

也没有了