golang的http客户端封装

简介

net/httpGo 语言标准库的一部分,它提供了创建 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 包的简单封装,使用者可以直接拿来用,减少了开发成本。

### 回答1: Go 语言的标准库中提供了 `net/http` 包,支持 HTTP 协议的客户端和服务端编程。Go 语言的并发模型让它特别适合用来编写高效的 HTTP 服务器。 使用 Go 语言编写 HTTP 服务器通常可以通过以下步骤来实现: 1. 实现一个处理器函数,该函数接受一个 `http.ResponseWriter` 和一个 `*http.Request` 参数,并使用它们来响应请求。 2. 使用 `http.HandleFunc` 函数将该处理器函数注册到一个路由上。 3. 使用 `http.ListenAndServe` 函数启动服务器。 例如,以下代码演示了如何在 8080 端口上启动一个服务器,并在根路径("/")上注册一个处理器函数,用于响应 HTTP GET 请求: ```go package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World!") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } ``` 在这个例子中,当客户端发起一个 HTTP GET 请求到根路径("/")时,服务器会调用处理器函数 `handler` 并将其写入响应。 希望这个回答对你有帮助。 ### 回答2: Go语言是一种开发高并发应用程序的优秀选择,它内置了强大的并发支持。在Go语言中,可以使用Goroutine和Channel来实现并发处理HTTP请求。 Goroutine是轻量级线程,可以在一个Go程序中同时运行多个Goroutine。可以将HTTP请求处理逻辑封装在一个Goroutine中,每个请求都会启动一个新的Goroutine来处理,从而实现并发处理。 Channel是Goroutine之间的通信机制,可以用于在Goroutine之间传递数据。在HTTP请求处理逻辑中,可以使用Channel来传递处理结果,例如将响应数据发送到一个Channel中,然后通过另一个Goroutine将数据写回响应。 使用Golang的net/http包可以方便地创建HTTP服务器。可以通过调用http.ListenAndServe函数来启动一个HTTP服务器,然后使用http.HandleFunc函数来注册处理HTTP请求的函数。在这个处理函数中,可以启动Goroutine来处理每个请求,再通过Channel将处理结果返回给主Goroutine。 在多个Goroutine之间共享数据时,需要注意并发访问的安全性。可以使用Golang提供的sync包中的互斥锁来保证并发访问的安全性。通过在访问共享数据的代码块中使用互斥锁进行锁定操作,可以防止多个Goroutine同时访问修改共享数据。 总的来说,使用Goroutine和Channel可以方便地实现Golang并发处理HTTP请求。通过合理地使用这些特性,可以提高系统的并发性能和稳定性。 ### 回答3: Golang是一种支持并发编程的编程语言,因此在Golang中实现并发的HTTP请求是非常简单的。Golang的标准库中提供了一个名为"net/http"的包,该包包含了处理HTTP请求和响应的相关函数和结构体。 通过使用GolangHTTP库,我们可以轻松地编写并发的HTTP请求代码。首先,我们可以使用"goroutine"来创建并发的执行环境,每个goroutine都可以处理一个HTTP请求。我们可以使用"net/http"包的"Get"函数创建一个HTTP请求,并将其放入goroutine中处理。例如,下面的代码展示了如何并发地向多个URL发送HTTP请求: ```go package main import ( "fmt" "net/http" ) func main() { urls := []string{"https://www.example.com", "https://www.google.com", "https://www.github.com"} for _, url := range urls { go func(u string) { resp, err := http.Get(u) if err != nil { fmt.Printf("Error fetching %s: %s\n", u, err.Error()) return } defer resp.Body.Close() fmt.Printf("Successfully fetched %s\n", u) }(url) } // 等待所有goroutine完成 for i := 0; i < len(urls); i++ { <-done } fmt.Println("All requests finished.") } ``` 在上面的例子中,我们使用一个包含三个URL的字符串切片作为输入,然后通过循环创建了三个goroutine,并发地向这些URL发送HTTP请求。每个goroutine都会调用"Get"方法发送请求,并在请求完成后打印相应的结果。 需要注意的是,我们使用了一个无缓冲的通道"done"来等待所有的goroutine结束。每个goroutine在完成处理请求后,都会通过"done"通道发送一个信号。通过在主函数中使用"<-"操作符从通道中接收信号,我们可以保证在所有的HTTP请求完成后再继续执行下面的操作。 通过上面的示例,我们可以看到,在Golang中实现并发的HTTP请求非常简单。通过使用goroutine和"net/http"包,我们可以轻松地编写高效且可扩展的并发代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我码玄黄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值