golang GET在运行时请求json类型错误

时间:2013-11-29 22:07:31

标签: json api go

我试图在golang中使用今天的RESTful api编写一个小应用程序,但是当我尝试解析来自api的GET请求时,似乎我在类型转换时出错。我的程序编译使我认为类型是正确的,但在运行时我的程序崩溃

我很清楚如何映射传入的json,其中没有预制结构来使用类型接口{} http://blog.golang.org/json-and-go

这是我的golang代码:

// get request to API
resp, err := http.Get("http://api.usatoday.com/open/articles/topnews/home?count=10&days=0&page=0&encoding=json&api_key=myApiKey")

if(err == nil){
    body, err := ioutil.ReadAll(resp.Body)
    if(err == nil) {
        var data interface{}
        json.Unmarshal(body, &data)

        var m = data.(map[string] []interface{})            
        var articles = m["stories"]
        var newArticle interface {}

        for newArticle = range articles {
            var n = newArticle.(map[string] string)

            fmt.Printf("<h2>Title: " + n["title"] + "</h2>")
            fmt.Printf("<p>description: " + n["description"] + "</p>")
            fmt.Printf("<p>link to article: " + n["link"] + "</p>")
        }

    } else {
        fmt.Println(err)
    }

} else {
    fmt.Println(err)
}

以下是get请求响应的一个小例子,如

{
    "stories": [{
        "description": "Despite the fact that shoppers descended upon stores after giving thanks, Black Friday wasn't without its share of brawls.",
        "guid": [{
            "isPermalink": "true",
            "value": "http:\/\/apidata.usatoday.com\/story\/news\/nation-now\/2013\/11\/29\/black-friday-police-violence\/3783467\/?kjnd=Pvzhnh75%2BZ3dnzxHVv571HQOfzKReZECsSPCBGnAiXlbHijpqdc3TQoe4dYfzVlB-8d81f9e3-0b56-421e-a5da-121f9eb83de3_E50GPTZL1%2FYloJsxpxSnp8AhoO2O9prQtDTYiwN3sbV0SfQ5wriH1zooo6XgNPTr"
        }],
        "link": "http:\/\/apidata.usatoday.com\/story\/news\/nation-now\/2013\/11\/29\/black-friday-police-violence\/3783467\/?kjnd=LOCSg6KVoQR3pwnZyGmcgcDZXwce0MwglPkURuQ%2BzMkUdNzQ2GXJr%2FPfLCl4Hf38-8d81f9e3-0b56-421e-a5da-121f9eb83de3_Zp5d44u%2F3U2IkXWRbNP0OwyXjRkEgShxoJC0wp7%2FOJoFPCI979Zw4qgNkWkOG1x1",
        "pubDate": "Fri, 29 Nov 2013 02:57:43 GMT",
        "title": "Black Friday frenzy leads to reports of violence"
    }, {
        "description": "President Obama's law faces hurdles beyond the Supreme Court case on the birth control mandate.",
        "guid": [{
            "isPermalink": "true",
            "value": "http:\/\/apidata.usatoday.com\/story\/news\/politics\/2013\/11\/29\/supreme-court-obamacare-lawsuits-irs\/3760811\/?kjnd=sCqadf244XkWTNcS0zAI%2Ba25XsnxwAX3ahu8NP0bzKdU4Kx31rJsa0cWlhvnwMl8-8d81f9e3-0b56-421e-a5da-121f9eb83de3_wtrtyHNPao7CqrB0IR7%2Bj3GFwJMhSYFSrOrrGZCkX2BStipIyyDtQoTLLFCGoLj0"
        }],
        "link": "http:\/\/apidata.usatoday.com\/story\/news\/politics\/2013\/11\/29\/supreme-court-obamacare-lawsuits-irs\/3760811\/?kjnd=Be2GdDxc2cZdIOPiCpcL9vz%2FFvmT859xSGoVutxwurqJ%2FCwvTt8vjs2s9MHzI1hO-8d81f9e3-0b56-421e-a5da-121f9eb83de3_88mb%2BwbADj1MvtG9%2BiYMhVS43CRGBEVdn0v5QJsORviARUA3qR0iE9LBr7NpNrT7",
        "pubDate": "Fri, 29 Nov 2013 11:12:08 GMT",
        "title": "Long-shot legal challenges to health care law abound"
    }
    }]
}

最后这是错误在运行时的样子

panic: interface conversion: interface is map[string]interface {}, not map[string][]interface {}

不确定我应该如何解决这个问题,因此任何拥有在golang中使用RESTful api的预先知识的人都会非常感激!

3 个答案:

答案 0 :(得分:2)

前面的愚蠢评论道歉,你提供的json无效,所以我验证了json有效负载,这是Unmarshalling +查询地图的一个工作示例

byt := []byte(`{
    "stories": [
        {
            "description": "Despite the fact that shoppers descended upon stores after giving thanks, Black Friday wasn't without its share of brawls.",
            "guid": [
                {
                    "isPermalink": "true",
                    "value": "http://apidata.usatoday.com/story/news/nation-now/2013/11/29/black-friday-police-violence/3783467/?kjnd=Pvzhnh75%2BZ3dnzxHVv571HQOfzKReZECsSPCBGnAiXlbHijpqdc3TQoe4dYfzVlB-8d81f9e3-0b56-421e-a5da-121f9eb83de3_E50GPTZL1%2FYloJsxpxSnp8AhoO2O9prQtDTYiwN3sbV0SfQ5wriH1zooo6XgNPTr"
                }
            ],
            "link": "http://apidata.usatoday.com/story/news/nation-now/2013/11/29/black-friday-police-violence/3783467/?kjnd=LOCSg6KVoQR3pwnZyGmcgcDZXwce0MwglPkURuQ%2BzMkUdNzQ2GXJr%2FPfLCl4Hf38-8d81f9e3-0b56-421e-a5da-121f9eb83de3_Zp5d44u%2F3U2IkXWRbNP0OwyXjRkEgShxoJC0wp7%2FOJoFPCI979Zw4qgNkWkOG1x1",
            "pubDate": "Fri, 29 Nov 2013 02:57:43 GMT",
            "title": "Black Friday frenzy leads to reports of violence"
        },
        {
            "description": "President Obama's law faces hurdles beyond the Supreme Court case on the birth control mandate.",
            "guid": [
                {
                    "isPermalink": "true",
                    "value": "http://apidata.usatoday.com/story/news/politics/2013/11/29/supreme-court-obamacare-lawsuits-irs/3760811/?kjnd=sCqadf244XkWTNcS0zAI%2Ba25XsnxwAX3ahu8NP0bzKdU4Kx31rJsa0cWlhvnwMl8-8d81f9e3-0b56-421e-a5da-121f9eb83de3_wtrtyHNPao7CqrB0IR7%2Bj3GFwJMhSYFSrOrrGZCkX2BStipIyyDtQoTLLFCGoLj0"
                }
            ],
            "link": "http://apidata.usatoday.com/story/news/politics/2013/11/29/supreme-court-obamacare-lawsuits-irs/3760811/?kjnd=Be2GdDxc2cZdIOPiCpcL9vz%2FFvmT859xSGoVutxwurqJ%2FCwvTt8vjs2s9MHzI1hO-8d81f9e3-0b56-421e-a5da-121f9eb83de3_88mb%2BwbADj1MvtG9%2BiYMhVS43CRGBEVdn0v5QJsORviARUA3qR0iE9LBr7NpNrT7",
            "pubDate": "Fri, 29 Nov 2013 11:12:08 GMT",
            "title": "Long-shot legal challenges to health care law abound"
        }
    ]
}`)

    var dat map[string][]map[string]interface{}

    if err := json.Unmarshal(byt, &dat); err != nil {
        panic(err)
    }

    fmt.Println(dat["stories"][1]["description"])

以上示例打印:

  奥巴马总统的法律面临着最高法院案件之外的障碍   节育任务。

编辑:添加了与地图变量相同的定义。

编辑2 :我调整示例以显示更高级别的查询。此外,这需要对定义的地图进行少量更改。

答案 1 :(得分:2)

我最终使用一些与json对象匹配的结构来修复它......这有点痛苦。

这里是否有人想在golang中使用这个api

type stories struct {
    Stories []story
}
type story struct {
    Description string
    Guid []guid
    Link string
    PubDate string
    Title string
}
type guid struct {
    IsPermalink string
    Value string
}

答案 2 :(得分:0)

万一有人好奇,这就是我的应用程序的最终功能看起来像使用我制作的结构:

func newsHandler(w *odie.ResponseWriter, req *odie.Request, vars odie.Context) {
    var count = vars.Get("numResults")
    if (count == "") {
        count = "10"
    }
    // get request to API
    resp, err := http.Get("http://api.usatoday.com/open/articles/topnews/home?count=" + count + "&days=0&page=0&encoding=json&api_key=myApiKey")

    if(err == nil){
        body, err := ioutil.ReadAll(resp.Body)
        if(err == nil) {
            var data stories
            err := json.Unmarshal(body, &data)

            if(err == nil) {
                for i:=0; i<len(data.Stories); i++ {
                    var article = data.Stories[i]

                    var link = strings.Split(article.Link,"apidata.")

                    fmt.Fprintf(w, "<h2>" + article.Title + "</h2>")
                    fmt.Fprintf(w, "<p>" + article.Description + "</p>")
                    if( len(link) > 1) {
                        fmt.Fprintf(w, "link to article: <a rel='nofollow' href=" + link[0] + link[1] + ">" + link[0] + link[1] + "</a><br/<br/>")
                    } else {
                        fmt.Fprintf(w, "link to article: <a rel='nofollow' href=" + link[0] + ">" + link[0] + "</a><br/<br/>")
                    }
                }           
            } else {
               fmt.Println(err)
            }

        } else {
            fmt.Println(err)
        }

    } else {
        fmt.Println(err)
    }
}