简介
net/http
是 Go
语言标准库的一部分,它提供了创建 HTTP
客户端和服务器的能力。这个包通过简化与 HTTP
协议的交互,让开发者能够方便地构建 HTTP
请求和响应,以及处理路由等任务。
本文以 net/http
包作为底层,封装一个包含 get
, post
, form-data
请求的工具包
开始
创建一个项目 demo
,并创建以下目录:
GET方法
在 client
文件中创建如下方法
package client import ( "bytes" "crypto/tls" "fmt" "io/ioutil" "net/http" "net/url" "time" ) /*** url 请求地址 header 头部 requestData 请求数据 */ func GET(path string,header map[string]string, requestData map[string]string) []byte { if(len(requestData) >0){ params := url.Values{} for k,v:=range requestData{ params.Add(k,v) } path = path + "?" + params.Encode() } req, _ := http.NewRequest("GET", path, bytes.NewBuffer([]byte(""))) req.Header.Set("cache-control", "no-cache") for key,value :=range header{ req.Header.Set(key, value) } //过滤https证书 tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //关闭连接池,不然会打满语句柄 DisableKeepAlives: true, } //设置请求超时时间为20秒 client := &http.Client{ Transport: tr, Timeout: 20 * time.Second, } res, err := client.Do(req) if res !=nil{ defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) return body } if err !=nil { fmt.Printf("请求错误: %s\n", err.Error()) return nil } return nil }
注意:此处需要关闭连接池,不然在多携程异步调用的时候,由于请求过多,会出现语句饼打满,导致请求报错的情况。
POST
/*** url 请求地址 header 头部 requestData 请求数据,json数据 */ func POST(path string,header map[string]string, requestData []byte) []byte { req, _ := http.NewRequest("POST", path, bytes.NewBuffer(requestData)) req.Header.Set("cache-control", "no-cache") _, ok := header["content-type"] if ok ==false { req.Header.Set("content-type", "application/json") } for key,value :=range header{ req.Header.Set(key, value) } //过滤https证书 tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //关闭连接池,不然会打满语句柄 DisableKeepAlives: true, } //设置请求超时时间为20秒 client := &http.Client{ Transport: tr, Timeout: 20 * time.Second, } res, err := client.Do(req) if res !=nil{ defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) return body } if err !=nil { fmt.Printf("请求错误: %s\n", err.Error()) return nil } return nil }
FormData
/*** url 请求地址 header 头部 params 其他请求参数 paramName 文件名称 path 本地文件路径 */ func FormData(url string,header map[string]string,params map[string]string, paramName, path string) []byte { file, err := os.Open(path) if err != nil { fmt.Printf("打开文件错误: %s\n", err.Error()) return nil } defer file.Close() body := &bytes.Buffer{} writer := multipart.NewWriter(body) //fmt.Printf("请求参数:%+v",params) part, err := writer.CreateFormFile(paramName, filepath.Base(path)) if err != nil { fmt.Printf("文件错误: %s\n", err.Error()) return nil } _, err = io.Copy(part, file) for key, val := range params { _ = writer.WriteField(key, val) } err = writer.Close() if err != nil { fmt.Printf("文件关闭错误: %s\n", err.Error()) return nil } req, err := http.NewRequest("POST", url, body) req.Header.Set("Content-Type", writer.FormDataContentType()) for key,value :=range header{ req.Header.Set(key, value) } //过滤https证书 tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //关闭连接池,不然会打满语句柄 DisableKeepAlives: true, } //设置请求超时时间为20秒 client := &http.Client{ Transport: tr, Timeout: 20 * time.Second, } res, err := client.Do(req) if res !=nil{ defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) return body } if err !=nil { fmt.Printf("请求错误: %s\n", err.Error()) return nil } return nil }
Request
/*** url 请求地址 header 头部 requestData 请求数据 method 请求方法 */ func Request(url string,header map[string]string, requestData []byte, method string) []byte{ //rwLock.Lock() //payload := strings.NewReader(requestData) req, _ := http.NewRequest(method, url, bytes.NewBuffer(requestData)) //req.Header.Set("content-type", "application/json") req.Header.Set("cache-control", "no-cache") for key,value :=range header{ req.Header.Set(key, value) } //过滤https证书 tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //关闭连接池,不然会打满语句柄 DisableKeepAlives: true, } //设置请求超时时间为20秒 client := &http.Client{ Transport: tr, Timeout: 20 * time.Second, } res, err := client.Do(req) if res !=nil{ defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) return body } if err !=nil { fmt.Printf("请求错误: %s\n", err.Error()) return nil } return nil }
测试
新建 main.go
文件写入以下内容:
func main() { sendData :=make(map[string]string) sendData["name"]="测试" sendData["sex"]="男" jsonStr,_:=json.Marshal(sendData) //此处需要换成你自己的接口地址 httpUrl:="https://xxxxx/api/test" headerData :=make(map[string]string) headerData["X-Ca-Key"]="22527885" headerData["Content-Type"]="application/json;charset=UTF-8" headerData["Accept"]="application/json" body:=client.POST(httpUrl,headerData,jsonStr) fmt.Printf("请求成功返回:%s\n",body) }
执行命令:
go run main.go
总结
本文对 net/http
包的简单封装,使用者可以直接拿来用,减少了开发成本。