| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- package http
-
- import (
- "encoding/base64"
- "net/http"
- "sync"
- "time"
-
- "git.x2erp.com/qdy/go-base/config"
- "github.com/go-resty/resty/v2"
- )
-
- // HTTPClient 简化的HTTP客户端
- type HTTPClient struct {
- client *resty.Client
- }
-
- // HTTPFactory HTTP客户端工厂
- type HTTPFactory struct {
- config config.IConfig
- client *resty.Client
- }
-
- var (
- httpFactoryInstance *HTTPFactory
- httpFactoryOnce sync.Once
- httpFactoryInitErr error
- )
-
- // GetHTTPFactory 获取HTTP工厂单例实例
- func GetHTTPFactory() (*HTTPFactory, error) {
- httpFactoryOnce.Do(func() {
- cfg := config.GetConfig()
-
- httpConfig := cfg.GetHTTPConfig()
-
- // 创建共享的resty客户端(线程安全)
- client := resty.New()
- client.SetTimeout(time.Duration(httpConfig.Timeout) * time.Second)
- client.SetTransport(&http.Transport{
- MaxIdleConns: httpConfig.MaxIdleConns,
- MaxIdleConnsPerHost: httpConfig.MaxIdleConnsPerHost,
- IdleConnTimeout: time.Duration(httpConfig.IdleConnTimeout) * time.Second,
- MaxConnsPerHost: httpConfig.MaxConnsPerHost,
- DisableCompression: httpConfig.DisableCompression,
- DisableKeepAlives: httpConfig.DisableKeepAlives,
- })
-
- // 设置默认headers
- client.SetHeaders(map[string]string{
- "Content-Type": "application/json",
- "Accept": "application/json",
- })
-
- httpFactoryInstance = &HTTPFactory{
- config: cfg,
- client: client,
- }
- })
-
- return httpFactoryInstance, httpFactoryInitErr
- }
-
- // CreateClient 创建HTTP客户端包装器(共享底层resty.Client)
- func (f *HTTPFactory) CreateClient() *HTTPClient {
- return &HTTPClient{
- client: f.client, // 共享同一个线程安全的客户端
- }
- }
-
- // GetUnderlyingClient 获取底层resty客户端(用于特殊场景)
- func (f *HTTPFactory) GetUnderlyingClient() *resty.Client {
- if f == nil {
- return nil
- }
- return f.client
- }
-
- // CreateClient 全局便捷函数:创建HTTP客户端
- func CreateClient() (*HTTPClient, error) {
- factory, err := GetHTTPFactory()
- if err != nil {
- return nil, err
- }
- return factory.CreateClient(), nil
- }
-
- // GetInitError 获取初始化错误(如果有)
- func GetInitError() error {
- return httpFactoryInitErr
- }
-
- // ==================== HTTPClient 方法 ====================
-
- // SetAuthToken 设置认证token(请求级别)
- func (c *HTTPClient) SetAuthToken(token string) *HTTPClient {
- // 注意:这里设置的是客户端级别的token,会影响所有使用该客户端的请求
- // 对于多用户场景,应该在请求级别设置
- c.client.SetAuthToken(token)
- return c
- }
-
- // SetBearerToken 设置Bearer Token认证头(请求级别)
- func (c *HTTPClient) SetBearerToken(token string) *HTTPClient {
- if token != "" {
- c.client.SetHeader("Authorization", "Bearer "+token)
- } else {
- c.client.Header.Del("Authorization")
- }
- return c
- }
-
- // SetBasicAuth 设置Basic认证头(请求级别)
- func (c *HTTPClient) SetBasicAuth(username, password string) *HTTPClient {
- if username != "" && password != "" {
- auth := username + ":" + password
- token := base64.StdEncoding.EncodeToString([]byte(auth))
- c.client.SetHeader("Authorization", "Basic "+token)
- } else {
- c.client.Header.Del("Authorization")
- }
- return c
- }
-
- // SetJSONContentType 设置Content-Type为application/json
- func (c *HTTPClient) SetJSONContentType() *HTTPClient {
- c.client.SetHeader("Content-Type", "application/json")
- return c
- }
-
- // SetHeader 设置请求头
- func (c *HTTPClient) SetHeader(key, value string) *HTTPClient {
- c.client.SetHeader(key, value)
- return c
- }
-
- // SetHeaders 批量设置请求头
- func (c *HTTPClient) SetHeaders(headers map[string]string) *HTTPClient {
- c.client.SetHeaders(headers)
- return c
- }
-
- // SetAuthHeaders 设置认证相关的headers
- func (c *HTTPClient) SetAuthHeaders(token string) *HTTPClient {
- return c.SetJSONContentType().SetBearerToken(token)
- }
-
- // SetBasicAuthHeaders 设置Basic认证相关的headers
- func (c *HTTPClient) SetBasicAuthHeaders(username, password string) *HTTPClient {
- return c.SetJSONContentType().SetBasicAuth(username, password)
- }
-
- // Post 发送POST请求(在请求级别设置认证信息,避免多用户相互影响)
- func (c *HTTPClient) Post(url string, data interface{}) (*resty.Response, error) {
- return c.client.R().SetBody(data).Post(url)
- }
-
- // PostWithResult 发送POST请求并解析结果
- func (c *HTTPClient) PostWithResult(url string, data interface{}, result interface{}) (*resty.Response, error) {
- return c.client.R().SetBody(data).SetResult(result).Post(url)
- }
-
- // PostWithAuth 发送带Bearer Token的POST请求(推荐用于多用户场景)
- func (c *HTTPClient) PostWithAuth(url string, data interface{}, token string, result interface{}) (*resty.Response, error) {
- req := c.client.R().SetBody(data)
- if token != "" {
- req.SetHeader("Authorization", "Bearer "+token)
- }
- if result != nil {
- req.SetResult(result)
- }
- return req.Post(url)
- }
-
- // Get 发送GET请求
- func (c *HTTPClient) Get(url string) (*resty.Response, error) {
- return c.client.R().Get(url)
- }
-
- // GetWithResult 发送GET请求并解析结果
- func (c *HTTPClient) GetWithResult(url string, result interface{}) (*resty.Response, error) {
- return c.client.R().SetResult(result).Get(url)
- }
-
- // GetWithAuth 发送带Bearer Token的GET请求(推荐用于多用户场景)
- func (c *HTTPClient) GetWithAuth(url string, token string, result interface{}) (*resty.Response, error) {
- req := c.client.R()
- if token != "" {
- req.SetHeader("Authorization", "Bearer "+token)
- }
- if result != nil {
- req.SetResult(result)
- }
- return req.Get(url)
- }
-
- // Put 发送PUT请求
- func (c *HTTPClient) Put(url string, data interface{}) (*resty.Response, error) {
- return c.client.R().SetBody(data).Put(url)
- }
-
- // PutWithResult 发送PUT请求并解析结果
- func (c *HTTPClient) PutWithResult(url string, data interface{}, result interface{}) (*resty.Response, error) {
- return c.client.R().SetBody(data).SetResult(result).Put(url)
- }
-
- // Delete 发送DELETE请求
- func (c *HTTPClient) Delete(url string) (*resty.Response, error) {
- return c.client.R().Delete(url)
- }
-
- // DeleteWithResult 发送DELETE请求并解析结果
- func (c *HTTPClient) DeleteWithResult(url string, result interface{}) (*resty.Response, error) {
- return c.client.R().SetResult(result).Delete(url)
- }
-
- // ==================== 便捷函数(修正版) ====================
-
- // PostJSON 便捷函数:直接发送POST请求
- func PostJSON(url string, data interface{}, result interface{}) (*resty.Response, error) {
- client, err := CreateClient()
- if err != nil {
- return nil, err
- }
-
- if result != nil {
- return client.PostWithResult(url, data, result)
- }
- return client.Post(url, data)
- }
-
- // PostJSONWithBearerToken 便捷函数:使用Bearer Token发送POST请求
- func PostJSONWithBearerToken(token, url string, data interface{}, result interface{}) (*resty.Response, error) {
- client, err := CreateClient()
- if err != nil {
- return nil, err
- }
-
- return client.PostWithAuth(url, data, token, result)
- }
-
- // PostJSONWithBasicAuth 便捷函数:使用Basic认证发送POST请求
- func PostJSONWithBasicAuth(username, password, url string, data interface{}, result interface{}) (*resty.Response, error) {
- client, err := CreateClient()
- if err != nil {
- return nil, err
- }
-
- // 为这个特定请求设置Basic Auth
- req := client.client.R().SetBody(data)
- if username != "" && password != "" {
- auth := username + ":" + password
- token := base64.StdEncoding.EncodeToString([]byte(auth))
- req.SetHeader("Authorization", "Basic "+token)
- }
- if result != nil {
- req.SetResult(result)
- }
- return req.Post(url)
- }
-
- // GetJSON 便捷函数:直接发送GET请求
- func GetJSON(url string, result interface{}) (*resty.Response, error) {
- client, err := CreateClient()
- if err != nil {
- return nil, err
- }
-
- if result != nil {
- return client.GetWithResult(url, result)
- }
- return client.Get(url)
- }
-
- // GetJSONWithBearerToken 便捷函数:使用Bearer Token发送GET请求
- func GetJSONWithBearerToken(token, url string, result interface{}) (*resty.Response, error) {
- client, err := CreateClient()
- if err != nil {
- return nil, err
- }
-
- return client.GetWithAuth(url, token, result)
- }
-
- // GetJSONWithBasicAuth 便捷函数:使用Basic认证发送GET请求
- func GetJSONWithBasicAuth(username, password, url string, result interface{}) (*resty.Response, error) {
- client, err := CreateClient()
- if err != nil {
- return nil, err
- }
-
- // 为这个特定请求设置Basic Auth
- req := client.client.R()
- if username != "" && password != "" {
- auth := username + ":" + password
- token := base64.StdEncoding.EncodeToString([]byte(auth))
- req.SetHeader("Authorization", "Basic "+token)
- }
- if result != nil {
- req.SetResult(result)
- }
- return req.Get(url)
- }
|