go語言http請求,包括文件上傳

最近在做開放平臺項目,需要用到HTTP請求,對HTTP請求做了簡單封裝。

封裝後的代碼可以實現:

  • Get提交
  • POST提交(表單)
  • POST提交(json)
  • POST提交(文件上傳)

完整代碼如下:

package common

import (
	"bytes"
	"encoding/json"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"
)

type UploadFile struct {
	// 表單名稱
	Name string
	// 文件全路徑
	Filepath string
}

// 請求客戶端
var httpClient = &http.Client{}

func Get(reqUrl string, reqParams map[string]string, headers map[string]string) string  {
	urlParams := url.Values{}
	Url, _ := url.Parse(reqUrl)
	for key, val := range reqParams {
		urlParams.Set(key, val)
	}

	//如果參數中有中文參數,這個方法會進行URLEncode
	Url.RawQuery = urlParams.Encode()
	// 得到完整的url,http://xx?query
	urlPath := Url.String()

	httpRequest,_ := http.NewRequest("GET", urlPath, nil)
	// 添加請求頭
	if headers != nil {
		for k, v := range headers {
			httpRequest.Header.Add(k,v)
		}
	}
	// 發送請求
	resp, err := httpClient.Do(httpRequest)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	response, _ := ioutil.ReadAll(resp.Body)
	return string(response)
}

func PostForm(reqUrl string, reqParams map[string]string, headers map[string]string) string {
	return post(reqUrl, reqParams, "application/x-www-form-urlencoded", nil, headers)
}

func PostJson(reqUrl string, reqParams map[string]string, headers map[string]string) string {
	return post(reqUrl, reqParams, "application/json", nil, headers)
}

func PostFile(reqUrl string, reqParams map[string]string, files []UploadFile, headers map[string]string) string {
	return post(reqUrl, reqParams, "multipart/form-data", files, headers)
}


func post(reqUrl string, reqParams map[string]string, contentType string, files []UploadFile, headers map[string]string) string  {
	requestBody, realContentType := getReader(reqParams, contentType, files)
	httpRequest,_ := http.NewRequest("POST", reqUrl, requestBody)
	// 添加請求頭
	httpRequest.Header.Add("Content-Type", realContentType)
	if headers != nil {
		for k, v := range headers {
			httpRequest.Header.Add(k,v)
		}
	}
	// 發送請求
	resp, err := httpClient.Do(httpRequest)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	response, _ := ioutil.ReadAll(resp.Body)
	return string(response)
}

func getReader(reqParams map[string]string, contentType string, files []UploadFile) (io.Reader, string)  {
	if strings.Index(contentType, "json") > -1 {
		bytesData, _ := json.Marshal(reqParams)
		return bytes.NewReader(bytesData), contentType
	} else if files != nil {
		body := &bytes.Buffer{}
		// 文件寫入 body
		writer := multipart.NewWriter(body)
		for _, uploadFile := range files {
			file, err := os.Open(uploadFile.Filepath)
			if err != nil {
				panic(err)
			}
			part, err := writer.CreateFormFile(uploadFile.Name, filepath.Base(uploadFile.Filepath))
			if err != nil {
				panic(err)
			}
			_, err = io.Copy(part, file)
			file.Close()
		}
		// 其他參數列表寫入 body
		for k, v := range reqParams {
			if err := writer.WriteField(k, v); err != nil {
				panic(err)
			}
		}
		if err := writer.Close(); err != nil {
			panic(err)
		}
		// 上傳文件需要自己專用的contentType
		return body, writer.FormDataContentType()
	} else {
		urlValues := url.Values{}
		for key, val := range reqParams {
			urlValues.Set(key, val)
		}
		reqBody:= urlValues.Encode()
		return strings.NewReader(reqBody), contentType
	}
}

使用方式:

  • Get請求
// url,請求參數,header
// 返回string
var response = Get(url, reqParams, headers);
  • POST表單
// url,請求參數,header
// 返回string
var response = PostForm(url, reqParams, headers)
  • POST JSON
// url,請求參數,header
// 返回string
 var response = PostJson(url, reqParams, headers)
  • POST 上傳文件,並且攜帶其他參數
files := []common.UploadFile{
		{Name:"file1", Filepath:path + "/test/aa.txt"},
		{Name:"file2", Filepath:path + "/test/bb.txt"},
	}
// url,請求參數,文件,header
// 返回string	
var response = PostFile(url, reqParams, files, headers)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章