我试图在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的预先知识的人都会非常感激!
答案 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)
}
}