【问题标题】:Translating CURL to Golang code将 CURL 转换为 Golang 代码
【发布时间】:2018-03-21 11:15:43
【问题描述】:

我正在尝试在 Golang 中执行这个确切的 CURL 命令:

curl -X GET -H "Content-Type: application/json" -H "WEB2PY-USER-TOKEN: token-string" -d '{"rfrID": "111111"}' 'url-string'

这有点奇怪,因为它是一个带有 JSON 主体的 GET HTTP 调用。然而,我们的供应商要求我们像这样调用 API。我不知道如何让我们的 Golang 程序执行这个 API。

这是迄今为止我尝试过的 Go 代码:

data := Payload{
    // fill struct
    RfrID: "111111",
}
payloadBytes, err := json.Marshal(data)
if err != nil {
    // handle err
}
body := bytes.NewReader(payloadBytes)

log.Printf("[INFO] Input body status: %v\n", body)

req, err := http.NewRequest("GET", "url-string", body)
if err != nil {
    // handle err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Web2py-User-Token", "token-string")

resp, err := http.DefaultClient.Do(req)
if err != nil {
    // handle err
}

log.Printf("[INFO] Artemis status: %v\n", resp)

defer resp.Body.Close()

在我的日志中打印以下内容:

2017/10/10 07:31:56 [INFO] Input body status: &{[123 34 114 102 114 73 68 34 58 34 49 49 49 49 49 49 34 125] 0 -1}

我希望这个主体是 JSON 主体,例如:

{"rfrID": "111111"}

【问题讨论】:

  • 显示到目前为止您尝试过的内容。
  • 这可能有用:mholt.github.io/curl-to-go
  • 谢谢,我已经添加了更多代码并尝试了该链接,但还没有弄明白

标签: http curl go


【解决方案1】:

你的身体就是你想象的那样,它只是以你意想不到的格式打印出来的。

bytes.NewReader() 返回一个指向结构类型bytes.Reader 的指针。当您使用log.Printf() 打印它时,它使用fmt 的包文档中定义的格式规则,即,指向struct 的指针打印为&{},并在其中枚举字段的值。这就是你所看到的。 bytes.Reader 将它提供的数据存储在一个字节切片中:

[123 34 114 102 114 73 68 34 58 34 49 49 49 49 49 49 34 125]

而且这个字节切片等价于你所期望的 JSON 字符串。验证:

data := []byte{123, 34, 114, 102, 114, 73, 68, 34, 58, 34, 49, 49, 49, 49, 49, 49, 34, 125}
fmt.Println(string(data))

输出:

{"rfrID":"111111"}

从这个阅读器读取将提供这个确切的字符串,如您在此示例中所见:

r := bytes.NewReader(data)
fmt.Println(r)
readData, err := ioutil.ReadAll(r)
if err != nil {
    panic(r)
}
fmt.Println(string(readData))

输出:

&{[123 34 114 102 114 73 68 34 58 34 49 49 49 49 49 49 34 125] 0 -1}
{"rfrID":"111111"}

Go Playground 上尝试这些示例。

区别

让我们检查一下 CURL 命令和您编写的客户端之间的区别,这个小应用程序将成为目标:

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    log.Println("Method:", r.Method)
    log.Println("Headers:", r.Header)
    log.Println("Form:", r.Form)
    data, err := ioutil.ReadAll(r.Body)
    log.Println("Body:", data, err)
    log.Println("Body string:", string(data))
})
panic(http.ListenAndServe(":8080", nil))

卷曲:

2017/10/10 10:17:26 Method: GET
2017/10/10 10:17:26 Headers: map[Content-Length:[19] User-Agent:[curl/7.47.0] Accept:[*/*] Content-Type:[application/json] Web2py-User-Token:[token-string]]
2017/10/10 10:17:26 Form: map[]
2017/10/10 10:17:26 Body: [123 34 114 102 114 73 68 34 58 32 34 49 49 49 49 49 49 34 125] <nil>
2017/10/10 10:17:26 Body string: {"rfrID": "111111"}

去客户端:

2017/10/10 10:17:20 Method: GET
2017/10/10 10:17:20 Headers: map[User-Agent:[Go-http-client/1.1] Content-Length:[18] Content-Type:[application/json] Web2py-User-Token:[token-string] Accept-Encoding:[gzip]]
2017/10/10 10:17:20 Form: map[]
2017/10/10 10:17:20 Body: [123 34 114 102 114 73 68 34 58 34 49 49 49 49 49 49 34 125] <nil>
2017/10/10 10:17:20 Body string: {"rfrID":"111111"}

尽管客户端自动添加了一些标头,并且 JSON 字符串中有一个空格(仅对格式化没有影响),但它们是相同的。

【讨论】:

  • 我的 CURL 命令是一个 GET 命令。它适用于 JSON 正文并返回我预期的结果。我 100% 确定供应商的文档说明了带有所述正文的 GET。
  • @RutgerHuijsmans 添加了测试以显示差异。除了一些微不足道的差异之外,它们是相同的。
  • 感谢 icza!现在完全有道理了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-29
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多