http - 将 CURL 转换为 Golang 代码

标签 http curl go

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

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

有点奇怪,因为它是一个带有 JSON 正文的 GET HTTP 调用。然而,我们的 vendor 要求我们像这样调用 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"}

最佳答案

你的 body 就是你所想的,它只是以一种你意想不到的格式打印出来。

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

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

而这个字节 slice 就相当于你期望的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))

curl :

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"}

Go 客户端:

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"}

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

关于http - 将 CURL 转换为 Golang 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46660105/

相关文章:

java - 拦截所有传出的http调用java

java - 服务器仅在 Java 客户端使用 urlConnection/httpUrlConnection 调用时返回 500 错误

rest - 如何将 SOAP 信封转换为 JSON?

python - pycurl 无信号和超时 <= 999ms

sql - sql golang执行查询时无效的内存地址或nil指针取消引用

go - 解释预分配 slice 的基准

c# - HttpWebRequest 在代码中抛出异常但在浏览器中不抛出异常

curl - 如何将curl命令转换为postman

php - curl: (26) 无法打开文件

http覆盖golang中的http头代码而json编码有错误