1 Star 0 Fork 0

robertzhai / go_common

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
request.go 5.99 KB
一键复制 编辑 原始数据 按行查看 历史
robertzhai 提交于 2023-06-16 12:07 . update
package httpclient
import (
"fmt"
"gitee.com/home_robertzhai/go_common/zap_logger"
"github.com/go-resty/resty/v2"
"net"
"net/http"
)
// HTTPRequest resty.Request的封装
type HTTPRequest struct {
request *resty.Request
httpclient *HTTPClient
logging bool
afterResponse []resty.ResponseMiddleware
}
// 默认log hook
var logAfterResponse resty.ResponseMiddleware = func(c *resty.Client, resp *resty.Response) error {
costTime := resp.Time().Nanoseconds() / 1e6
r := resp.Request.RawRequest
_ = r.ParseForm()
body := resp.Body()
str := fmt.Sprintf("Request:\n%s %s%s %s\t", r.Method, r.URL.Host, r.URL.RequestURI(), r.Proto) +
fmt.Sprintf("HEADERS: %s\t", composeHeaders(r.Header)) +
fmt.Sprintf("Body: %v\n", resp.Request.Body) +
fmt.Sprintf("FormData: %v\n", resp.Request.FormData) +
fmt.Sprintf("Response: \nStatus:%d\t", resp.StatusCode()) +
fmt.Sprintf("Body:%s\t", string(body)) +
fmt.Sprintf("CostTime: %dms\t", costTime)
if resp.Request.Error != nil {
str += fmt.Sprintf("Error: %v", resp.Request.Error)
zap_logger.Error(nil, logTag, str)
} else {
zap_logger.Info(nil, logTag, str)
}
return nil
}
// Get http get 请求
func (hr *HTTPRequest) Get(url string) (*resty.Response, error) {
return hr.execute(http.MethodGet, url)
}
// Post http post 请求
func (hr *HTTPRequest) Post(url string) (*resty.Response, error) {
return hr.execute(http.MethodPost, url)
}
// OnAfterResponse 响应后置钩子函数, 区别于client的 OnAfterResponseHook
// OnAfterResponse可以在响应报err后继续执行
// OnAfterResponse的执行顺序要后于client的 OnAfterResponseHook
// 响应成功的后置操作建议使用client的 OnAfterResponseHook,需要响应失败的后置操作使用此函数
func (hr *HTTPRequest) OnAfterResponseHook(f resty.ResponseMiddleware) *HTTPRequest {
hr.afterResponse = append(hr.afterResponse, f)
return hr
}
// execute return response errors
func (hr *HTTPRequest) execute(method, url string) (*resty.Response, error) {
resp, err := hr.request.Execute(method, url)
if err != nil {
// 响应发生错误时,client中的defaultAfterResponseHook不会被触发
// 这里加上对于超时的监控收集
netErr, ok := err.(net.Error)
if ok && netErr.Timeout() {
_ = defaultAfterResponseHook(hr.httpclient.client, resp)
}
hr.request.SetError(err)
}
if hr.logging && resp != nil {
hr.OnAfterResponseHook(logAfterResponse)
}
// TODO 这里的error暂时未捕获,升级1.13后使用wrap包装
for _, f := range hr.afterResponse {
_ = f(hr.httpclient.client, resp)
}
return resp, err
}
// EnableLogging 开启日志
func (hr *HTTPRequest) EnableLogging() *HTTPRequest {
hr.logging = true
return hr
}
// SetHeader 设置Header
func (hr *HTTPRequest) SetHeader(header, value string) *HTTPRequest {
hr.request.Header[header] = []string{value}
return hr
}
// SetHeaders 设置多个Header字段
func (hr *HTTPRequest) SetHeaders(headers map[string]string) *HTTPRequest {
for h, v := range headers {
hr.request.Header[h] = []string{v}
}
return hr
}
// SetHeader 设置Header
func (hr *HTTPRequest) SetHeaderV2(header, value string) *HTTPRequest {
hr.request.SetHeader(header, value)
return hr
}
// SetHeaders 设置多个Header字段
func (hr *HTTPRequest) SetHeadersV2(headers map[string]string) *HTTPRequest {
for h, v := range headers {
hr.request.SetHeader(h, v)
}
return hr
}
// SetQueryParam 设置query参数
func (hr *HTTPRequest) SetQueryParam(param, value string) *HTTPRequest {
hr.request = hr.request.SetQueryParam(param, value)
return hr
}
// SetQueryParams 设置多个query参数
func (hr *HTTPRequest) SetQueryParams(params map[string]string) *HTTPRequest {
hr.request = hr.request.SetQueryParams(params)
return hr
}
// SetPathParams 设置动态url path
func (hr *HTTPRequest) SetPathParams(params map[string]string) *HTTPRequest {
hr.request = hr.request.SetPathParams(params)
return hr
}
// SetResult 如果响应状态码在200到299之间且Content-Type为application/json或Type为application/xml,设置自动解码对象
// 注:res 可以是指针或非指针
func (hr *HTTPRequest) SetResult(res interface{}) *HTTPRequest {
hr.request = hr.request.SetResult(res)
return hr
}
// SetContentLength 是否需要设置header中ContentLength的值
func (hr *HTTPRequest) SetContentLength(l bool) *HTTPRequest {
hr.request = hr.request.SetContentLength(l)
return hr
}
// SetBody 设置body参数
// 支持 JSON string SetBody(`{"username":"testuser", "password":"testpass"}`)
// 支持 []byte array SetBody([]byte(`{"username":"testuser", "password":"testpass"}`))
// 支持 Struct SetBody(User{Username: "testuser", Password: "testpass"})
// 支持 Map SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"})
// 注 Content-Type为json格式时,支持以上四项,Content-Type为xml时,仅支持后两项,因为Struct和Map方式需要序列化支持
func (hr *HTTPRequest) SetBody(body interface{}) *HTTPRequest {
hr.request = hr.request.SetBody(body)
return hr
}
// SetFormData 设置表单参数,仅支持Post, 自动设置Content-Type为application/x-www-form-urlencoded
func (hr *HTTPRequest) SetFormData(data map[string]string) *HTTPRequest {
hr.request = hr.request.SetFormData(data)
return hr
}
// SetFile 设置文件名称与路径用于上传, 自动设置Content-Type为multipart/form-data
func (hr *HTTPRequest) SetFile(filename, filepath string) *HTTPRequest {
hr.request = hr.request.SetFile(filename, filepath)
return hr
}
// SetFiles 设置多个文件信息用于上传
// SetFiles(map[string]string{
// "my_file1": "/Users/jeeva/Gas Bill - Sep.pdf",
// "my_file2": "/Users/jeeva/Electricity Bill - Sep.pdf",
// "my_file3": "/Users/jeeva/Water Bill - Sep.pdf",
//})
func (hr *HTTPRequest) SetFiles(files map[string]string) *HTTPRequest {
hr.request = hr.request.SetFiles(files)
return hr
}
func (hr *HTTPRequest) EnableTrace() *HTTPRequest {
hr.request = hr.request.EnableTrace()
return hr
}
func (hr *HTTPRequest) TraceInfo() resty.TraceInfo {
return hr.request.TraceInfo()
}
Go
1
https://gitee.com/home_robertzhai/go_common.git
git@gitee.com:home_robertzhai/go_common.git
home_robertzhai
go_common
go_common
v1.1.0

搜索帮助

53164aa7 5694891 3bd8fe86 5694891