goland http客户端封装接口

按照惯例,首先贴代码

package util

import (
	"fmt"
	"net/http"
	"time"
	"regexp"
	"strings"
	"io"
	"bytes"
	"mime/multipart"
	"os"
	"net/url"
	"crypto/tls"
	"crypto/x509"
	"io/ioutil"
	"errors"
)

type MultiPart struct {
	Name string
	Path string
}
type Client struct {
	// 服务端CA证书
	HttpsPemFile         string
	ClientPemFile 		 string
	ClientKeyFile 		 string
	Request 			*http.Request

	Method  			string
	Url 				string
	Query 				map[string]string
	RequestHeader   	map[string]string
	RequestBody     	string
	RequestBodyType 	string
	RequestForm     	map[string]string
	RequestMultiPart 	map[string][]MultiPart
	TimeOut 			time.Duration
	ResponseData 		*http.Response
	ResponseHeader		http.Header
	ResponseStatusCode  int
	ResponseBody 		[]byte

	ErrType 			int 		// 0正常,1-100 请求错误,101-200 发送错误 201-300 返回错误
	ErrMessage 			error
	IsSuccess 			bool
	RequestLong 		float64

}

func ( T *Client)Send(){
	defer T.Execution()
	// 设置UrlQuery
	if T.Query != nil {
		if  isR,_ := regexp.Match("\\?" , []byte(T.Url) ); !isR  {
			T.Url += "?"
		}else{
			T.Url += "&"
		}
		for k,v :=range T.Query {
			T.Url += k+"="+v+"&"
		}
		T.Url = strings.Trim( T.Url , "&")
	}
	// 定义POST数据

	var ioReader io.Reader
	// 定义要上传文件 或者带FORM数据
	if T.RequestMultiPart != nil {
		bodyBuffer := &bytes.Buffer{}
		bodyWriter := multipart.NewWriter(bodyBuffer)
		for k,v := range T.RequestMultiPart{
			for _,Postmultipart := range v {
				fileWriter, _ := bodyWriter.CreateFormFile( k ,Postmultipart.Name )
				file, _ := os.Open(Postmultipart.Path)
				defer file.Close()
				io.Copy(fileWriter, file)
			}
		}
		if T.RequestForm != nil {
			for k,v :=  range T.RequestForm {
				_ = bodyWriter.WriteField(k, v)
			}
		}
		T.RequestHeader["Content-Type"] = bodyWriter.FormDataContentType()
		ioReader = bodyBuffer
	}else {
		if T.RequestBody != "" {
			ioReader = bytes.NewBuffer([]byte(T.RequestBody))
			// 注意要定义定义格式
		}else{
			if T.RequestForm != nil {
				var u url.Values
				for k,v := range T.RequestForm {
					u.Set(k ,v )
				}
				ioReader = strings.NewReader( u.Encode() )
			}
		}
	}


	// 定义请求结构
	var requestErr error
	T.Request, requestErr = http.NewRequest( T.Method, T.Url, ioReader  )
	if requestErr != nil {
		T.ErrType   = 1
		T.ErrMessage =  requestErr
		return
	}

	//  设置发送的数据

	// 设置 HEADER 信息
	if T.RequestHeader != nil {
		for k,v := range T.RequestHeader {
			if strings.ToLower( k ) == "host" {
				T.Request.Host = v
			}else{
				T.Request.Header.Set( k , v )
			}
		}
	}

	//  发送请求

	client := &http.Client{}
	if isHttps,_ := regexp.Match( "^https" , []byte(T.Url) ) ;isHttps {
		if T.HttpsPemFile == "" {
			client.Transport = &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			}
		}else{
			TLSClientConfig := &tls.Config{}

			pool := x509.NewCertPool()
			aCrt , crtErr := ioutil.ReadFile(T.HttpsPemFile )
			if crtErr != nil {
				T.ErrType 		= 98
				T.ErrMessage 	= crtErr
				return
			}
			pool.AppendCertsFromPEM( aCrt )

			TLSClientConfig.RootCAs = pool

			// 双向加密校验
			if T.ClientPemFile != "" && T.ClientKeyFile != "" {
				cliCrt, cliErr := tls.LoadX509KeyPair(T.ClientPemFile , T.ClientKeyFile )
				if cliErr != nil {
					T.ErrType 		= 97
					T.ErrMessage 	= cliErr
					return
				}
				TLSClientConfig.Certificates = []tls.Certificate{cliCrt}
			}

			client.Transport = &http.Transport{
				TLSClientConfig: TLSClientConfig ,
			}
		}
	}

	// 设置超时
	if T.TimeOut != 0 {
		client.Timeout = T.TimeOut
	}
	now := time.Now()

	response , responseError := client.Do( T.Request )

	T.RequestLong = float64(time.Now().Sub( now ))/1000000

	if  responseError != nil {
		//  发送错误
		T.ErrType 		= 101
		T.ErrMessage 	= responseError
		return
	}

	defer response.Body.Close()
	T.ResponseHeader 		=  response.Header
	T.ResponseStatusCode 	=  response.StatusCode
	body, bodyerr := ioutil.ReadAll(response.Body)
	if bodyerr != nil {
		T.ErrType 		= 201
		T.ErrMessage 	= bodyerr
	}
	T.ResponseBody = body
	T.IsSuccess    = true
}

func ClientNew( url  string ) *Client {
	T :=  &Client{}
	T.Url = url
	return T
}

// 设置超时
func (T *Client) SetTimeOut( second int ) *Client {
	T.TimeOut = time.Duration( second )
	return T
}
// 设置提交方式
func (T *Client) SetMethod( method string ) *Client{
	T.Method = strings.ToUpper( method )
	return T
}
// 设置query
func ( T *Client )SetQuery( query map[string]string ) *Client{
	T.Query = query
	return T
}
// 设置Header
func ( T *Client)SetHeader( header map[string]string ) *Client{
	T.RequestHeader = header
	return T
}
// 设置FormData
func ( T *Client)SetFormData( data map[string]string ) *Client{
	T.RequestForm =  data
	return T
}
// 设置multipart

func ( T *Client)SetMultiPart( data map[string][]MultiPart) *Client {
	T.RequestMultiPart =  data
	return T
}

func ( T *Client)SetRequestBody(  body string ) *Client{
	T.RequestBody = body
	return T
}

func ( T *Client )Execution(){
	if err := recover(); err != nil {
		T.ErrType = -1
		T.ErrMessage = errors.New( fmt.Sprintf("%s", err ) )
	}
}

func ( T *Client )SetHttpsPemFile( path string ){
	T.HttpsPemFile =  path
}

func ( T *Client)SetClientPemFile( path string  ){
	T.ClientPemFile =  path
}
func ( T *Client)SetClientKeyFile( path string  ){
	T.ClientKeyFile =  path
}

get和post调用示例

import (
	"fmt"
	"github.com/gin-gonic/gin"
)
import "项目/library/util"

func GetAction( c *gin.Context){
	httpclient := util.ClientNew("https://api.xxx.com/buy/product/viplist")
	//httpclient.SetMethod("GET").Send()
	var urlQuery  = make(map[string]string)
		urlQuery["market"] = "huaweipay"
		urlQuery["os"] = "android"
	httpclient.SetMethod("GET").SetQuery(urlQuery).Send()
	code := httpclient.ResponseStatusCode
	var response string
	if code == 200{
		response = string(httpclient.ResponseBody)
	}
	fmt.Println( code )
	c.String(200,response)
}

func PostAction(c *gin.Context){
	httpclient := util.ClientNew("https://api.xxx.cn/viplist/myvip")
	var urlQuery = make(map[string]string)
		urlQuery["datatype"] = "2"
	type postjson  struct {
		 Uid int `json:"uid"`
		 Usertoken string `json:"usertoken"`
		 Pid string `json:"pid"`
		 Appid int `json:"appid"`
	}
	jsondata := &postjson{}
	jsondata.Uid = 1
	jsondata.Usertoken = "1121213###1!!!44348assaa(:111"
	jsondata.Pid = "vip1"
	jsondata.Appid = 1
	jsonByte,err := json.Marshal(jsondata )
	if err != nil {
		// shib
	}
	requestBody := string( jsonByte)
	httpclient.SetMethod("POST").SetQuery(urlQuery).SetRequestBody( requestBody ).Send()
	code := httpclient.ResponseStatusCode
	var response string
	if code == 200{
		response = string(httpclient.ResponseBody)
	}
	fmt.Println( code )
	c.String(200,response)
}
RIPRO主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
荐书网 » goland http客户端封装接口

发表评论

提供最优质的资源集合

立即查看 了解详情