Golang:来自URL的Json作为地图

时间:2015-07-05 13:18:11

标签: json rest go

从网址中提取json的最佳方式是什么,即Go的Rest服务? 此外,似乎大多数其他客户端库都强制使用json.marshall,需要使用它的结构。

这对于非结构化数据的情况不起作用,你不完全知道将要发生什么。有没有办法让它全部只是作为一个地图[string:string]?

2 个答案:

答案 0 :(得分:0)

为什么不将其解析为map [string]字符串,因为此代码必须执行

var d map[string]interface{}
data, err := json.Unmarshal(apiResponse, &d)

您也可以遍历此结构中的数据。

如果您怀疑,api响应可能不是单个对象,而是对象集合,interface{}也适用于数组。

答案 1 :(得分:0)

如果您不知道消息中的内容,您可能会遇到几种情况。

依赖于类型

的消息内容

类型通常由某个类型字段指示。在这种情况下,您可以使用包含所有类型字段的“union”结构:

type Foo struct {
    A int
    B string
}

type Bar struct {
    C int
    D string
}

type Message struct {
    Type string
    Foo
    Bar
}

// or this, if you have common fields

type Message struct {
    Type string
    A int
    B string
    C int
    D string
}

将消息解组到union结构中,在类型上调度,然后选择子结构。

var m Message
json.Unmarshal(data, &m)
switch m.Type {
    case "foo":
        ...
    case "bar":
        ...
}

完全动态的消息

在这种情况下,您拥有一组不相关的键值并单独处理它们。

解析为map[string]interface{}。当然,缺点是必须强制转换每个值并检查其类型。 警告: map[string]interface{}会将所有数字转换为浮点数,甚至是整数,因此您已将它们转换为float64

您也可以使用map[string]json.RawMessage,如果您不想解析值,则只有密钥(json.RawMessage[]byte,并且在解组时保留原样。)

带有动态有效负载的

“Envelope”消息

例如:

{
    "type": "foo",
    "payload": {
        "key1": "value1"
    }
}

{
    "type": "bar",
    "payload": {
        "key2": "value2",
        "key3": [1, 2]
    }
}

使用带json.RawMessage的结构。

type Message struct {
    Type string
    Payload json.RawMessage
}

type Foo struct {
    Key1 string
}

type Bar struct {
    Key2 string
    Key3 []int
}

解析包络(有效负载将被保留),然后在类型上调度,并将有效负载解析为子结构。

var m Message
_ = json.Unmarshal(data, &m)
switch m.Type {
    case "foo":
        var payload Foo
        _ = json.Unmarshal(m.Payload, &payload)
        // do stuff
    case "bar":
        var payload Bar
        _ = json.Unmarshal(m.Payload, &payload)
        // do stuff
}