Go语言Http调用之Get、Post请求详解
HTTP 调用需要通过 http 包里的 Client 结构体里的 Do 方法去实现,因此需要先声明一个 Client 结构体变量,该结构体可以设置超时时间等配置。
对于一个请求里的 URL,查询参数,请求 method 等参数,需要 http 包里的 Request 结构体去封装。我们可以通过 NewRequestWithContext 或 NewRequest 函数获取一个基础的 Request 结构体指针变量。
NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error)
- 参数
ctx为Context的接口类型,任意实现Context接口的自定义类型都可以作为此参数传递。 - 参数
method为HTTP方法参数,可选值有GET、POST、DELETE、PUT等。 - 参数
url为接口的请求路径。 - 参数
body,为请求体参数。
通过 client.Do(req) 方法调用之后,返回值有 (*Response, error),第一个是响应结构体参数,第二个是错误参数。通过读取 Response 的 body 的值,可以获取接口的响应体。
一、GET
import (
"context"
"fmt"
"io"
"net/http"
)
func main() {
client := http.Client{}
request, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://localhost:8080/user?name=tom", nil)
if err != nil {
return
}
request.Header.Set("headerParam", "header")
resp, err := client.Do(request)
if err != nil {
fmt.Println(err)
return
}
bytes, err := io.ReadAll(resp.Body)
if err != nil {
return
}
defer resp.Body.Close()
fmt.Println(string(bytes)) // {"code":0,"data":{"list":[{"name":"小明","age":20},{"name":"小红","age":18}]},"message":"success"}
}
- 需要携带查询参数时,可以直接拼接在
url字符串上面。 header参数可以通过 request 结构体的Header字段的set方法或add方法进行设置。- HTTP 请求响应码可以通过
Response的StatusCode字段进行查看。 - 接口请求成功之后,通过
io.ReadAll方法,读取resp.Body响应体信息。 - 除了直接在
url上拼接query参数的方式,我们还可以通过以下方式进行添加query参数:
params := url.Values{}
rawUrl, err := url.Parse("http://localhost:8080/user")
if err != nil {
return
}
params.Set("name", "tom")
rawUrl.RawQuery = params.Encode()
u := rawUrl.String()
通过 url.Values 结构体的 set 方法设置 query参数,url 通过 url.Parse 函数生成一个 URL 结构体指针变量,rawUrl.RawQuery = params.Encode() 通过这行代码将 query 参数和 url 进行绑定,最后通过 String() 方法将 url 转换成 string 类型。
二、POST
发起 HTTP POST 请求时,携带 json 格式的 body 参数是最常见的,这是因为 json 格式的参数可读性好,对于层级结构较为复杂的数据也能应对,并且这符合 RestFul API 的规范。因此以下的示例为:发送 HTTP POST 请求,并携带 json 类型的 body 参数。
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
)
type User struct {
Username string `json:"username"`
Password string `json:"password"`
}
func main() {
client := http.Client{}
user := User{
Username: "123456",
Password: "12346",
}
dataByte, err := json.Marshal(user)
if err != nil {
fmt.Println(err)
}
bodyReader := bytes.NewReader(dataByte)
request, err := http.NewRequestWithContext(context.Background(), http.MethodPost, "http://localhost:8080/user", bodyReader)
if err != nil {
return
}
request.Header.Set("Content-Type", "application/json")
resp, err := client.Do(request)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("statusCode: ", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
if err != nil {
return
}
defer resp.Body.Close()
fmt.Println(string(body))
}
- 首先定义
User结构体,创建结构体变量 user,通过json.Marshal函数,将user转成[]byte数据,然后通过bytes.NewReader函数,将[]byte数据转成Reader指针变量。 http.NewRequestWithContext函数,最后一个参数是为body参数,接收的变量类型是Reader接口的实现体。第一步将user转成Reader指针变量就是为了在这里进行传递。- 传递
json类型的body参数,需要在请求头参数里设置Content-Type的值为application/json。
如果是发送 application/x-www-form-urlencoded 类型的表单数据,需要改写 body 参数的生成代码:
values := url.Values{}
values.Set("username", "1234")
values.Set("password", "1234")
bodyReader := strings.NewReader(values.Encode())
本文通过 POST 请求,介绍了如何传递 json 类型和 application/x-www-form-urlencoded 类型的 body 参数。对于 HTTP 中的 query 参数和 body 参数的如何传递,上下两篇文章已经通过例子进行介绍。虽然举的例子是 GET 和 POST 请求,如果想要调用 PUT、DELETE 等请求,只需要在 NewRequestWithContext 函数中,指定第二个参数为 http.MethodPut、http.MethodDelete 等就行。
浙公网安备 33010602011771号