如何在Go中解析此JSON字符串?

时间:2013-02-05 14:22:46

标签: json go

有问题的JSON字符串如下所示:

{
"development":{
    "connector":[
         {"id":"connector-server-1", "host":"127.0.0.1", "port":4050, "wsPort":3050},
         {"id":"connector-server-2", "host":"127.0.0.1", "port":4051, "wsPort":3051},
         {"id":"connector-server-3", "host":"127.0.0.1", "port":4052, "wsPort":3052}
     ],
    "chat":[
         {"id":"chat-server-1", "host":"127.0.0.1", "port":6050},
         {"id":"chat-server-2", "host":"127.0.0.1", "port":6051},
         {"id":"chat-server-3", "host":"127.0.0.1", "port":6052}
    ],
    "gate":[
     {"id": "gate-server-1", "host": "127.0.0.1", "wsPort": 3014}
]
},
"production":{
   "connector":[
         {"id":"connector-server-1", "host":"127.0.0.1", "port":4050, "wsPort":3050},
         {"id":"connector-server-2", "host":"127.0.0.1", "port":4051, "wsPort":3051},
         {"id":"connector-server-3", "host":"127.0.0.1", "port":4052, "wsPort":3052}
     ],
    "chat":[
         {"id":"chat-server-1", "host":"127.0.0.1", "port":6050},
         {"id":"chat-server-2", "host":"127.0.0.1", "port":6051},
         {"id":"chat-server-3", "host":"127.0.0.1", "port":6052}
    ],
    "gate":[
     {"id": "gate-server-1", "host": "127.0.0.1", "wsPort": 3014}
]
}
}

我想用这样的代码解析它:

package config

import(
    "sync"
    "io/ioutil"
    "encoding/json"
    "errors"
    "log"
)

type Service struct {
    Id string `json:"id"`
    Host string `json:"host"`
    Port uint `json:"port"`
    QueryPort uint `json:"queryPort"`
    WsPort uint `json:"wsPort"`
    ServiceType string 
}

type Config struct {
    Services []Service
    Master Service
    Mutex sync.RWMutex
}

func LoadServers(filepath, env string) (*Config, error) {
    // 读取文件
    content, err := ioutil.ReadFile(filepath)
    if err != nil {
        return nil, err
    }

    configs := make(map[string]map[string][]Service, 0)
    err = json.Unmarshal(content, configs)
    if err != nil {
        return nil, err
    }
}

我希望我的代码将此JSON字符串解析为map[string]map[string][]Service

但它显示错误:

json: Unmarshal(non-pointer map[string]map[string][]config.Service)

2 个答案:

答案 0 :(得分:6)

configs的地址传递给json.Unmarshal。例如,

configs := make(map[string]map[string][]Service, 0)
err = json.Unmarshal(content, &configs)
if err != nil {
    return nil, err
}
fmt.Println(configs)

输出:

map[production:map[connector:[{connector-server-1 127.0.0.1 4050 0 3050 } {connector-server-2 127.0.0.1 4051 0 3051 } {connector-server-3 127.0.0.1 4052 0 3052 }] gate:[{gate-server-1 127.0.0.1 0 0 3014 }] chat:[{chat-server-1 127.0.0.1 6050 0 0 } {chat-server-2 127.0.0.1 6051 0 0 } {chat-server-3 127.0.0.1 6052 0 0 }]] development:map[chat:[{chat-server-1 127.0.0.1 6050 0 0 } {chat-server-2 127.0.0.1 6051 0 0 } {chat-server-3 127.0.0.1 6052 0 0 }] gate:[{gate-server-1 127.0.0.1 0 0 3014 }] connector:[{connector-server-1 127.0.0.1 4050 0 3050 } {connector-server-2 127.0.0.1 4051 0 3051 } {connector-server-3 127.0.0.1 4052 0 3052 }]]]
&{[] {  0 0 0 } {{0 0} 0 0 0 0}}

答案 1 :(得分:3)

要建立在@ peterSO的答案上,如果您想要一些奇特的东西,encoding/json包具有Decoder类型,这允许您直接从io.Reader解码JSON,是os.File满足的接口。

这样您就可以使用os包而不是io/ioutil,这可以为您节省导入(看作ioutil已导入os。)

package main

import (
    "fmt"
    "encoding/json"
    "os"
)

func main() {
    pathToFile := "jsondata.txt"

    file, err := os.OpenFile(pathToFile, os.O_RDONLY, 0644)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    configs := make(map[string]map[string][]Service, 0)
    err = json.NewDecoder(file).Decode(&configs)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
}

这样,您可以直接从文件或数据流解码JSON。如果你做一些简单的事情并希望避免这种事情,那可能就没必要了,但是还是要注意的事情。

祝你好运!