我试图从web读取JSON数据,但该代码返回空结果。我不知道我在这里做错了。
package main import "os" import "fmt" import "net/http" import "io/IoUtil" import "encoding/json" type Tracks struct { Toptracks []Toptracks_info } type Toptracks_info struct { Track []Track_info Attr []Attr_info } type Track_info struct { Name string Duration string Listeners string Mbid string Url string Streamable []Streamable_info Artist []Artist_info Attr []Track_attr_info } type Attr_info struct { Country string Page string PerPage string TotalPages string Total string } type Streamable_info struct { Text string Fulltrack string } type Artist_info struct { Name string Mbid string Url string } type Track_attr_info struct { Rank string } func get_content() { // json data url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands" res,err := http.Get(url) if err != nil { panic(err.Error()) } body,err := IoUtil.ReadAll(res.Body) if err != nil { panic(err.Error()) } var data Tracks json.Unmarshal(body,&data) fmt.Printf("Results: %v\n",data) os.Exit(0) } func main() { get_content() }
发布此处为未来的Google员工,因为这是排名在许多搜索与获取和解码JSON的顶部结果。
理想的方式是不使用IoUtil.ReadAll,而是直接在阅读器上使用解码器。这里有一个很好的函数,它获取一个url并将其响应解码到目标结构上。
var myClient = &http.Client{Timeout: 10 * time.Second} func getJson(url string,target interface{}) error { r,err := myClient.Get(url) if err != nil { return err } defer r.Body.Close() return json.NewDecoder(r.Body).Decode(target) }
使用示例:
type Foo struct { Bar string } func main() { foo1 := new(Foo) // or &Foo{} getJson("http://example.com",foo1) println(foo1.Bar) // alternately: foo2 := Foo{} getJson("http://example.com",&foo2) println(foo2.Bar) }
更新:因为这已经得到了相当多的关注,我想补充说,你不应该使用默认的* http.Client结构在生产中,因为这个答案最初演示! (这是什么http.Get / etc调用)。原因是默认客户端没有设置超时;如果远程服务器没有响应,你会有一个糟糕的一天。我更新了上面的答案。