117 lines
2.8 KiB
Go
117 lines
2.8 KiB
Go
package api
|
||
|
||
import (
|
||
"bytes"
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"net/http"
|
||
)
|
||
|
||
// HTTPClient 封装了常用的HTTP请求方法
|
||
type HTTPClient struct {
|
||
Client *http.Client
|
||
}
|
||
|
||
// NewHTTPClient 创建一个新的HTTP客户端
|
||
func NewHTTPClient() *HTTPClient {
|
||
return &HTTPClient{
|
||
Client: &http.Client{},
|
||
}
|
||
}
|
||
|
||
// Get 发送GET请求
|
||
func (c *HTTPClient) Get(url string, headers map[string]string) ([]byte, error) {
|
||
req, err := http.NewRequest("GET", url, nil)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("创建GET请求失败: %v", err)
|
||
}
|
||
|
||
// 设置请求头
|
||
for key, value := range headers {
|
||
req.Header.Set(key, value)
|
||
}
|
||
|
||
resp, err := c.Client.Do(req)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("发送GET请求失败: %v", err)
|
||
}
|
||
defer resp.Body.Close()
|
||
|
||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||
body, _ := io.ReadAll(resp.Body)
|
||
return nil, fmt.Errorf("GET请求失败,状态码: %d, 响应体: %s", resp.StatusCode, string(body))
|
||
}
|
||
|
||
body, err := io.ReadAll(resp.Body)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("读取响应体失败: %v", err)
|
||
}
|
||
|
||
return body, nil
|
||
}
|
||
|
||
// PostJSON 发送JSON格式的POST请求
|
||
func (c *HTTPClient) PostJSON(url string, data interface{}, headers map[string]string) ([]byte, error) {
|
||
jsonData, err := json.Marshal(data)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("JSON序列化失败: %v", err)
|
||
}
|
||
|
||
return c.Post(url, jsonData, "application/json", headers)
|
||
}
|
||
|
||
// Post 发送POST请求
|
||
func (c *HTTPClient) Post(url string, data []byte, contentType string, headers map[string]string) ([]byte, error) {
|
||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
|
||
if err != nil {
|
||
return nil, fmt.Errorf("创建POST请求失败: %v", err)
|
||
}
|
||
|
||
// 设置Content-Type
|
||
req.Header.Set("Content-Type", contentType)
|
||
|
||
// 设置其他请求头
|
||
for key, value := range headers {
|
||
req.Header.Set(key, value)
|
||
}
|
||
|
||
resp, err := c.Client.Do(req)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("发送POST请求失败: %v", err)
|
||
}
|
||
defer func(Body io.ReadCloser) {
|
||
err = Body.Close()
|
||
if err != nil {
|
||
fmt.Printf("关闭响应体失败: %v\n", err)
|
||
}
|
||
}(resp.Body)
|
||
|
||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||
body, _ := io.ReadAll(resp.Body)
|
||
return nil, fmt.Errorf("POST请求失败,状态码: %d, 响应体: %s", resp.StatusCode, string(body))
|
||
}
|
||
|
||
body, err := io.ReadAll(resp.Body)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("读取响应体失败: %v", err)
|
||
}
|
||
|
||
return body, nil
|
||
}
|
||
|
||
// GetWithQuery 发送带查询参数的GET请求
|
||
func (c *HTTPClient) GetWithQuery(url string, params map[string]string, headers map[string]string) ([]byte, error) {
|
||
// 构建查询参数
|
||
if len(params) > 0 {
|
||
url += "?"
|
||
for key, value := range params {
|
||
url += fmt.Sprintf("%s=%s&", key, value)
|
||
}
|
||
// 移除最后一个多余的 &
|
||
url = url[:len(url)-1]
|
||
}
|
||
|
||
return c.Get(url, headers)
|
||
}
|