一、概述
http 包提供 HTTP 客户端和服务器实现。
官方文档 https://pkg.go.dev/net/http 我们可以多看几遍。
主要的提供的方法有 Get、Head、Post 和 PostForm 。
我们实现的话get请求的话,主要有2种方式
http.Get()
DefaultClient.Get()
然后我们会介绍封装参数,header,transport
二、2种实现方式
2.1 最简单的 http.Get()方法
我们使用http的Get()函数
func Get(url string ) (resp * Response , err error )
Get方法 向指定的 URL 发出 GET。
Get 是 DefaultClient.Get 的包装器。用于没有自定义header的快速请求。
func Test1(t *testing.T) {
url := fmt.Sprintf("http://localhost:8080/v1/user?id=%d", 1010)
resp, err := http.Get(url)
if err != nil {
}
// 客户端发起的请求必须在结束的时候关闭 response body
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
t.Log(resp, err)
t.Log(string(body))
}
这个代码,我们可以等价替换为DefaultClient.Get如下
func Test1t(t *testing.T) {
url := fmt.Sprintf("http://localhost:8080/v1/user?id=%d", 1010)
resp, err := http.DefaultClient.Get(url)
if err != nil {
}
// 客户端发起的请求必须在结束的时候关闭 response body
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
t.Log(resp, err)
t.Log(string(body))
}
2.2 使用http.NewRequest() 封装header以及param参数
我们先使用 http.NewRequest() 生产一个 Request
然后再使用 http.DefaultClient.Do(Request)来 请求这个Request。
func Test5(t *testing.T) {
req, err := http.NewRequest("GET", "http://localhost:8080/v1/discovery", nil)
if err != nil {
}
// 增加header
req.Header.Add("Content-Type", "application/json")
// 增加请求参数
params := req.URL.Query()
params.Add("id", "1010")
req.URL.RawQuery = params.Encode()
resp, err := http.DefaultClient.Do(req)
// 客户端发起的请求必须在结束的时候关闭 response body
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
t.Log(resp, err)
t.Log(string(body))
}
我们这里封装了一个 header请求数据类型Content-Type,用json的格式来请求和处理返回数据。
并且我们处理了 url请求参数 params
三、自定义client
在前面的请求,其实我们用的都是默认的DefaultClient,如果我们想自己定义client,来做一些http的处理呢。
在这里我们自定义http.Client,来控制一下 http请求与返回的标准。
func Test3(t *testing.T) {
// 要控制代理、TLS 配置、保持活动、压缩和其他设置,请创建一个Transport:
client := &http.Client{
Transport: &http.Transport{
Proxy: nil,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second, // 连接超时时间
Deadline: time.Time{},
KeepAlive: 30 * time.Second, // 连接保持超时时间
}).DialContext,
DialTLSContext: nil,
TLSClientConfig: nil,
TLSHandshakeTimeout: 10 * time.Second, // TLS安全连接握手超时时间,
DisableKeepAlives: false,
DisableCompression: false,
MaxIdleConns: 100, // client对与所有host最大空闲连接数总和
MaxIdleConnsPerHost: 2, // 每个host 最大空闲链接数
IdleConnTimeout: 90 * time.Second, // 空闲连接在连接池中的超时时间
ResponseHeaderTimeout: 0,
ExpectContinueTimeout: 1 * time.Second, // 发送完请求到接收到响应头的超时时间,
MaxResponseHeaderBytes: 0,
WriteBufferSize: 0,
ReadBufferSize: 0,
},
Timeout: 1000 * time.Millisecond, // 总的超时时间
}
url := fmt.Sprintf("http://localhost:8080/v1/discovery?id=%d", 1010)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
}
resp, err := client.Do(req)
// the client must close the response body when finished with it:
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
t.Log(resp, err)
t.Log(string(body))
}
可以发现在 最后我们用 client.Do()来代替了默认的DefaultClient.Do
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。