Go语言HTTP客户端封装实战:GET、POST和FormData请求
创作时间:
作者:
@小白创作中心
Go语言HTTP客户端封装实战:GET、POST和FormData请求
引用
CSDN
1.
https://blog.csdn.net/qq_30333063/article/details/139383756
本文将详细介绍如何使用Go语言的标准库net/http来封装HTTP客户端,包括GET、POST和FormData请求的方法。通过封装这些常用请求方式,可以大大减少开发成本,提高开发效率。
简介
net/http是Go语言标准库的一部分,它提供了创建HTTP客户端和服务器的能力。这个包通过简化与HTTP协议的交互,让开发者能够方便地构建HTTP请求和响应,以及处理路由等任务。
本文将以net/http包作为底层,封装一个包含GET、POST、FormData请求的工具包。
开始
创建一个项目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包的简单封装,使用者可以直接拿来用,减少了开发成本。
热门推荐
值机柜台怎么取登机牌和办理托运(超全的旅客乘机流程)
姑姑带娃神器大揭秘!
世界摄影日:打卡重庆最美机位!
先有鸡还是先有蛋?这得从恐龙说起……
进化论:误解与抵抗
厦门十大特色美食:从沙茶面到土笋冻,必尝的闽南美味
中国网友教美国妈妈盐蒸橙子治感冒,效果真有那么好?医生提醒
训练前补水指南:如何科学饮水提升运动表现
德阳装修补贴最新消息:这些政策你需要知道
揭秘景泰蓝高价现象:工艺难度与文化传承的双重价值
景泰蓝:探索中国铜胎掐丝珐琅的千年艺术
科学饮食助力孩子长高:从营养到管理的全面指南
《射雕英雄传:侠之大者》:肖战演技遭吐槽,徐克的武侠新篇为何难获内地观众认可?
徐克新作《射雕英雄传》,魔改还是经典?
曹操麾下十大谋士排名及结局
数据说话:郭嘉在曹操阵营的真实地位到底如何?
《三国演义》与《三国志》里曹操的形象相比,有哪些不同的地方?
网友看三国演义,受不了东吴鼠辈的称呼,结果翻开正史更生气了!
协和医院专家提醒:秋冬季节警惕蘑菇中毒,这些急救知识要记牢!
远离野生毒蘑菇,不做“菇勇者”
秋冬季节如何安全采摘羊肚菌?
警惕!这些毒蘑菇让你分分钟中毒
南沙:从荒芜滩涂到岭南水乡明珠
南沙湿地探秘:黄山鲁森林公园徒步攻略
南沙湿地:红树林里的生物天堂
广州南沙:红树林保护与湿地修复的生态建设样本
世界湿地日:加入南沙环保行动吧!
登上春晚的外卖诗人王计兵,为春节写下了这些诗
大兴机场到北京西高铁时刻表新鲜出炉!
血糖高的人能喝蜂蜜吗?血糖偏高能吃蜂王浆吗?