当前位置: 首页 > 知识库问答 >
问题:

如何从http获取JSON响应。得到

孟鸿德
2023-03-14

我试图从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()
}

共有3个答案

商茂勋
2023-03-14
匿名用户

为了让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()
}

雍志新
2023-03-14

您的问题是数据结构中的切片声明(除了轨道,它们不应该是切片…)。取回的json文件中有一些相当愚蠢的字段名,这些字段名可以通过structtags修复,请参见godoc。

下面的代码成功解析了json。如果你还有其他问题,请告诉我。

package main

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 `json: "@attr"`
}

type Track_info struct {
    Name       string
    Duration   string
    Listeners  string
    Mbid       string
    Url        string
    Streamable Streamable_info
    Artist     Artist_info   
    Attr       Track_attr_info `json: "@attr"`
}

type Attr_info struct {
    Country    string
    Page       string
    PerPage    string
    TotalPages string
    Total      string
}

type Streamable_info struct {
    Text      string `json: "#text"`
    Fulltrack string
}

type Artist_info struct {
    Name string
    Mbid string
    Url  string
}

type Track_attr_info struct {
    Rank string
}

func perror(err error) {
    if err != nil {
        panic(err)
    }
}

func get_content() {
    url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands"

    res, err := http.Get(url)
    perror(err)
    defer res.Body.Close()

    decoder := json.NewDecoder(res.Body)
    var data Tracks
    err = decoder.Decode(&data)
    if err != nil {
        fmt.Printf("%T\n%s\n%#v\n",err, err, err)
        switch v := err.(type){
            case *json.SyntaxError:
                fmt.Println(string(body[v.Offset-40:v.Offset]))
        }
    }
    for i, track := range data.Toptracks.Track{
        fmt.Printf("%d: %s %s\n", i, track.Artist.Name, track.Name)
    }
}

func main() {
    get_content()
}

花永昌
2023-03-14

理想的方法是不使用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。客户生产中的结构与此答案最初演示的一样!(这是http.Get/etc调用的内容)。原因是默认客户端没有设置超时;如果远程服务器没有响应,您将度过糟糕的一天。

 类似资料:
  • 问题内容: 我想从Http get响应中获取一个对象: 这是我当前对Http get的代码: 这是convertSteamToString函数: 现在,我只是得到一个字符串对象。我如何找回JSON对象。 问题答案: 您获得的字符串只是JSON Object.toString()。这意味着您将获取JSON对象,但使用String格式。 如果应该获取JSON对象,则可以输入:

  • 我想从Http get响应中获取一个对象: 这是我当前的Http get代码: 这是转换的SteamToString函数: 现在我只是得到一个字符串对象。如何取回JSON对象。

  • 问题内容: 我正在尝试从Web读取JSON数据,但是该代码返回空结果。我不确定我在做什么错。 问题答案: 理想的方法 不是 使用,而是直接在阅读器上使用解码器。这是一个不错的函数,它获取url并将其响应解码到结构上。 使用示例: 您不应该在生产中使用默认结构,如最初回答的那样!(/ etc调用的是哪个)。原因是默认客户端没有设置超时。如果远程服务器无响应,那将是糟糕的一天。

  • 我正在尝试从json的响应中获取正文并打印这个json或能够将他放入数组。我在堆栈上找到了这篇文章:如何从http.Get获得JSON响应。有代码: 但是我不明白为什么会有“Decode(target)”和“target interface{}”。它是做什么的?为什么当我试着打印json时?NewDecoder(r.Body)没有什么有意义的。

  • 我一直在努力学习关于如何使用的最简单的教程,我认为这是与相比的下一个最棒的教程。 例如,https://www.baeldung.com/spring-5-webclient#4-geting-a-response 因此,当我尝试对https://petstore.swagger.io/v2/pet/findbystatus?status=available执行同样的操作时,

  • 问题内容: 我是Node开发的新手,我正在尝试使用具有JSON响应的RESTful协议进行服务器端API调用。我已经阅读了API文档和本SO帖子。 我试图从轨道总线中提取的API并以JSON输出返回数据。我对如何使用实际URL中的所有参数和选项发出HTTP GET请求感到困惑。甚至可以通过浏览器或使用“ curl”命令来访问API及其响应。http://developer.cumtd.com/ap