【问题标题】:Reading and Unmarshalling API results in Golang在 Golang 中读取和解组 API 结果
【发布时间】:2021-07-08 08:15:22
【问题描述】:

在下面的程序中,我从 API 中提取了一些数据。

它输出一个相当复杂的数据。 当我ioutil.ReadAll(resp.Body) 时,结果是[]uint8 类型。 如果我尝试读取结果,它只是一个随机整数数组。

但是,如果我使用 string(diskinfo) 将其转换为字符串,我就可以读取它 但我想在 Struct 中使用它并且无法解组。

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "reflect"
)

type ApiResults struct {
    results []struct {
        statement_id int `json.statement_id`
        series       []struct {
            name string `json.name`
            tags struct {
                host string `json.host`
            }
            columns []string      `json.columns`
            values  []interface{} `json.values`
        }
    }
}

func main() {
    my_url := "my_url"
    my_qry := fmt.Sprintf("my_query")

    resp, err := http.Get(my_url + url.QueryEscape(my_qry))
    if err != nil {
        fmt.Printf("ERROR:  %v\n", err)
    } else {
        fmt.Println(reflect.TypeOf(resp))
        diskinfo, _ := ioutil.ReadAll(resp.Body)
        fmt.Println(reflect.TypeOf((diskinfo)))
        fmt.Println(diskinfo)
        fmt.Println(string(diskinfo))
        diskinfo_string := string(diskinfo)
        data := ApiResults{}
        json.Unmarshal([]byte(diskinfo_string), &data)
        //fmt.Printf("Values = %v\n", data.results.series.values)
        //fmt.Printf("Server = %v\n", data.results.series.tags.host)
    }
}

如果我将数据视为一个字符串,我会得到这个(格式化):

{"results":[
  {"statement_id":0,
   "series":[
    {"name":"disk",
     "tags":{"host":"myServer1"},
     "columns":["time","disk_size"],
     "values":[["2021-07-07T07:53:32.291490387Z",1044]]},
    {"name":"disk",
     "tags":{"host":"myServer2"},
     "columns":["time","disk_size"],
     "values":[["2021-07-07T07:53:32.291490387Z",1046]]}
  ]}
]}

我认为我的 Apireturn 结构的结构也不正确,因为 API 结果包含多个主机的信息。 但首先,我怀疑数据是否必须以不同的格式发送到结构。完成此操作后,我可能会尝试弄清楚接下来如何从 Struct 中读取数据。

【问题讨论】:

    标签: go struct


    【解决方案1】:

    ioutil.ReadAll 已经为您提供byte[] 类型的数据。因此,您只需调用json.Unmarshal 将其作为参数传递即可。

    import (
        "encoding/json"
        "io/ioutil"
        "net/http"
    )
    
    
    func toStruct(res *http.Response) (*ApiResults, error) {
        body, err := ioutil.ReadAll(res.Body)
        if err != nil {
            return nil, err
        }
    
        defer res.Body.Close()
    
        data := ApiResults{}
        if err := json.Unmarshal(body, &data); err != nil {
            return nil, err
        }
    
        return data, nil 
    }
    

    您的结构似乎也有问题。 struct标签的正确使用方法如下。另外,需要导出字段才能使 json 标记(由 json.Umarshal 使用)才能工作 - 以大写开头即可。

    type ApiResults struct {
        Results []struct {
            StatementId int `json:"statement_id"`
            Series       []struct {
                Name string `json:"name"`
                Tags struct {
                    Host string `json:"host"`
                } `json:"tags"`
                Columns []string      `json:"columns"`
                Values  []interface{} `json:"values"`
            } `json:"series"`
        } `json:"results"`
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      • 2014-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-15
      相关资源
      最近更新 更多