【问题标题】:Parsing REST API Response解析 REST API 响应
【发布时间】:2018-10-09 13:25:03
【问题描述】:

我是 golang 的新手。我正在编写一个程序来解析 API 的 json 响应:https://httpbin.org/get。我使用以下代码来解析响应:

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "os"
)

type Headers struct {
    Close  string `json:"Connection"`
    Accept string `json:"Accept"`
}

type apiResponse struct {
    Header Headers `json:"headers"`
    URL    string  `json:"url"`
}

func main() {
    apiRoot := "https://httpbin.org/get"
    req, err := http.NewRequest("GET", apiRoot, nil)
    if err != nil {
        fmt.Println("Couldn't prepare request")
        os.Exit(1)
    }
    response, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    defer response.Body.Close()
    var responseStruct apiResponse
    err = json.NewDecoder(response.Body).Decode(&responseStruct)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    fmt.Printf("%v\n", responseStruct)
}

当我运行这段代码时,输​​出是:

$ go run parse.go
{{close } https://httpbin.org/get}

从输出中,我们可以看到 json 响应中的“Accept”键没有被解码。为什么会这样?如何从响应正文中解析该字符串?

【问题讨论】:

  • 标题不是正文的一部分。它们已经“预读”并解析为http.Repsonse.Header
  • @mkopriva:不是标题,这里显示的内容来自响应的正文。您可以通过邮递员进行测试
  • @Arun 响应反映了您发送 URL 的请求标头。您的浏览器发送的标头与 Go http 客户端不同。
  • @Not_a_Golfer:我了解情况。我已经设置了和浏览器一样的标题,我得到了结果。
  • @Arun 我的错,我看错了你的问题。

标签: json parsing go


【解决方案1】:

您的代码运行良好,但在这里我认为您的 Accept 密钥不会从 API 返回,这就是它没有显示 Accept 值的原因。要检查结构的keyvalue 对,请使用下面的print 方法。

fmt.Printf("%+v\n", responseStruct)

为了克服这种情况,您需要在请求API 之前将带有请求的Accept 发送到header,例如:

req.Header.Set("Accept", "value")
response, err := hc.Do(req)
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}

然后您将在decoded 结构中获得Accept 值:

{Header:{Accept:value Close:close} URL:https://httpbin.org/get}

【讨论】:

  • 本地运行代码,响应不包含Accept值。
  • @saddam:我已经打印了,但它不包含 Accept。它显示{Header:{Accept: Close:close} URL:https://httpbin.org/get}
  • @Arun 您从 httpbin 获得的响应不包含 Accept,因为您没有发送 Accept 标头。寄一份,你会得到一份。
【解决方案2】:

apiResponse 未导出 - 您需要将其更改为 APIResponse 之类的内容。您可能会发现将要解码的 JSON 粘贴到 https://mholt.github.io/json-to-go/ 中会生成您需要的所有代码!

type AutoGenerated struct {
    Args struct {
    } `json:"args"`
    Headers struct {
        Accept                  string `json:"Accept"`
        AcceptEncoding          string `json:"Accept-Encoding"`
        AcceptLanguage          string `json:"Accept-Language"`
        Connection              string `json:"Connection"`
        Dnt                     string `json:"Dnt"`
        Host                    string `json:"Host"`
        UpgradeInsecureRequests string `json:"Upgrade-Insecure-Requests"`
        UserAgent               string `json:"User-Agent"`
    } `json:"headers"`
    Origin string `json:"origin"`
    URL    string `json:"url"`
}

【讨论】:

  • 我认为未导出的 apiResponse 不是问题,因为我是从同一个文件中调用它的。感谢您提供json-to-go 工具的链接。
  • 正确 - 需要导出 JSON 包以获取它们的成员。 play.golang.org/p/P2QRiaE6Gfg 表明只要 API 返回您期望的标头,您的代码就可以正常工作。
猜你喜欢
  • 1970-01-01
  • 2017-05-08
  • 2016-12-14
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多