为了账号安全,请及时绑定邮箱和手机立即绑定

带有令牌身份验证的 Golang REST api 请求到 json 数组响应

带有令牌身份验证的 Golang REST api 请求到 json 数组响应

Go
偶然的你 2022-11-08 16:15:40
编辑这是工作代码,以防有人发现它有用。这个问题的标题最初是“How to parse a list fo dicts in golang”。这是标题不正确,因为我引用了我在 python 中熟悉的术语。package mainimport (    "encoding/json"    "fmt"    "io/ioutil"    "log"    "net/http")//Regional Struttype Region []struct {    Region      string `json:"region"`    Description string `json:"Description"`    ID          int    `json:"Id"`    Name        string `json:"Name"`    Status      int    `json:"Status"`    Nodes       []struct {        NodeID    int    `json:"NodeId"`        Code      string `json:"Code"`        Continent string `json:"Continent"`        City      string `json:"City"`    } `json:"Nodes"`}//working request and responsefunc main() {    url := "https://api.geo.com"    // Create a Bearer string by appending string access token    var bearer = "TOK:" + "TOKEN"    // Create a new request using http    req, err := http.NewRequest("GET", url, nil)    // add authorization header to the req    req.Header.Add("Authorization", bearer)    //This is what the response from the API looks like    //regionJson := `[{"region":"GEO:ABC","Description":"ABCLand","Id":1,"Name":"ABCLand [GEO-ABC]","Status":1,"Nodes":[{"NodeId":17,"Code":"LAX","Continent":"North America","City":"Los Angeles"},{"NodeId":18,"Code":"LBC","Continent":"North America","City":"Long Beach"}]},{"region":"GEO:DEF","Description":"DEFLand","Id":2,"Name":"DEFLand","Status":1,"Nodes":[{"NodeId":15,"Code":"NRT","Continent":"Asia","City":"Narita"},{"NodeId":31,"Code":"TYO","Continent":"Asia","City":"Tokyo"}]}]`    //Send req using http Client    client := &http.Client{}    resp, err := client.Do(req)    if err != nil {        log.Println("Error on response.\n[ERROR] -", err)    }    defer resp.Body.Close()    body, err := ioutil.ReadAll(resp.Body)    if err != nil {        log.Println("Error while reading the response bytes:", err)    }    var regions []Region    json.Unmarshal([]byte(body), &regions)    fmt.Printf("Regions: %+v", regions)}
查看完整描述

1 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

看看这个操场上的例子以获得一些指示。


这是代码:


package main


import (

    "encoding/json"

    "log"

)


func main() {

    b := []byte(`

[

  {"key": "value", "key2": "value2"},

  {"key": "value", "key2": "value2"}

]`)


    var mm []map[string]string

    if err := json.Unmarshal(b, &mm); err != nil {

        log.Fatal(err)

    }


    for _, m := range mm {

        for k, v := range m {

            log.Printf("%s [%s]", k, v)

        }

    }

}

我重新格式化了您包含的 API 响应,因为它不是有效的 JSON。


在 Go 中,需要定义类型以匹配 JSON 模式。


我不知道为什么 API 会附加%到结果的末尾,所以我忽略了这一点。如果包含它,您将需要在解组之前从文件中修剪结果。


你从解组中得到的是一张地图。然后,您可以遍历切片以获取每个映射,然后遍历每个映射以提取keys 和 alues v。


更新

在您更新的问题中,您包含不同的 JSON 模式,并且此更改必须通过更新类型反映在 Go 代码中。您的代码中还有其他一些错误。根据我的评论,我鼓励你花一些时间学习这门语言。


package main


import (

    "bytes"

    "encoding/json"

    "io/ioutil"

    "log"

)


// Response is a type that represents the API response

type Response []Record


// Record is a type that represents the individual records

// The name Record is arbitrary as it is unnamed in the response

// Golang supports struct tags to map the JSON properties

// e.g. JSON "region" maps to a Golang field "Region"

type Record struct {

    Region      string `json:"region"`

    Description string `json:"description"`

    ID          int    `json:"id"`

    Nodes       []Node

}

type Node struct {

    NodeID int    `json:"NodeId`

    Code   string `json:"Code"`

}


func main() {

    // A slice of byte representing your example response

    b := []byte(`[{

        "region": "GEO:ABC",

        "Description": "ABCLand",

        "Id": 1,

        "Name": "ABCLand [GEO-ABC]",

        "Status": 1,

        "Nodes": [{

            "NodeId": 17,

            "Code": "LAX",

            "Continent": "North America",

            "City": "Los Angeles"

        }, {

            "NodeId": 18,

            "Code": "LBC",

            "Continent": "North America",

            "City": "Long Beach"

        }]

    }, {

        "region": "GEO:DEF",

        "Description": "DEFLand",

        "Id": 2,

        "Name": "DEFLand",

        "Status": 1,

        "Nodes": [{

            "NodeId": 15,

            "Code": "NRT",

            "Continent": "Asia",

            "City": "Narita"

        }, {

            "NodeId": 31,

            "Code": "TYO",

            "Continent": "Asia",

            "City": "Tokyo"

        }]

    }]`)


    // To more closely match your code, create a Reader

    rdr := bytes.NewReader(b)


    // This matches your code, read from the Reader

    body, err := ioutil.ReadAll(rdr)

    if err != nil {

        // Use Printf to format strings

        log.Printf("Error while reading the response bytes\n%s", err)

    }


    // Initialize a variable of type Response

    resp := &Response{}

    // Try unmarshaling the body into it

    if err := json.Unmarshal(body, resp); err != nil {

        log.Fatal(err)

    }


    // Print the result

    log.Printf("%+v", resp)

}


查看完整回答
反对 回复 2022-11-08
  • 1 回答
  • 0 关注
  • 103 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信