幾種常用內(nèi)容類型(Content-Type)的http客戶端開發(fā)實例
在開發(fā)過程中,通常會遇到與其他服務(wù)做信息交換的情況厕鹃,大多數(shù)情況下會通過http接口實現(xiàn)信息的交換。但是不同的服務(wù)接口指定的Content-Type類型是不同的噪馏。下文將通過實際的例子展示序苏,常用的集中內(nèi)容類型的http請求如何開發(fā)。
Content-Type(內(nèi)容類型)这弧,一般是指網(wǎng)頁中存在的 Content-Type娃闲,用于定義網(wǎng)絡(luò)文件的類型和網(wǎng)頁的編碼,決定瀏覽器將以什么形式匾浪、什么編碼讀取這個文件皇帮,這就是經(jīng)常看到一些 PHP 網(wǎng)頁點擊的結(jié)果卻是下載一個文件或一張圖片的原因蛋辈。
Content-Type 標頭告訴客戶端實際返回的內(nèi)容的內(nèi)容類型属拾。s
http支持的Content-Type種類很多,但是實際中常用的主要有三種:application/x-www-form-urlencoded梯浪,application/form-data捌年,application/json。
1挂洛、一個通用的請求方法
var httpTr = &http.Transport{
//控制主機的最大空閑連接數(shù)礼预,0為沒有限制
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
//長連接在關(guān)閉之前,保持空閑的最長時間虏劲,0表示沒限制托酸。
IdleConnTimeout: 60 * time.Second,
}
var client = &http.Client{
Timeout: 20 * time.Second,
Transport: httpTr,
}
func SendRequest(url string, method string, contentType string, param io.Reader, respData interface{}, headers ...map[string]string) error {
var err error
req, err := http.NewRequest(method, url, param)
if err != nil {
err = fmt.Errorf("create http request failed: %s", err.Error())
return err
}
req.Header.Set("Content-Type", contentType)
if headers != nil {
for _, h := range headers {
for k, v := range h {
req.Header.Set(k, v)
}
}
}
resp, err := client.Do(req)
if err != nil {
err = fmt.Errorf("send http request failed: %s", err.Error())
return err
}
defer resp.Body.Close()
respBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
err = fmt.Errorf("read response data failed: %s", err.Error())
return err
}
logger.Debug("read the response ok:", string(respBytes))
// 解析響應(yīng)
if err = json.Unmarshal(respBytes, respData); err != nil {
logger.Error(err.Error())
err = fmt.Errorf("unmarshal response data failed: %s", err.Error())
return err
}
return nil
}
2褒颈、application/json格式
func PostJsonRequest(url string, requestData interface{}, responseData interface{}, headers ...map[string]string) error {
var err error
logger.Debugf("url: %s, req: %+v", url, requestData)
jsonParamBytes, err := json.Marshal(requestData)
if err != nil {
err = fmt.Errorf("Marshal json error:%s ", err.Error())
return err
}
logger.Debugf("request json:%s", string(jsonParamBytes))
paramData := bytes.NewBuffer(jsonParamBytes)
err = SendRequest(url, "POST", "application/json", paramData, responseData, headers...)
if err != nil {
return err
}
return nil
}
3、application/x-www-form-urlencoded格式
func PostUrlEncodedRequest(urlstr string, requestData map[string]string, responseData interface{}) error {
var err error
var body = make(url.Values)
if requestData != nil {
for k, v := range requestData {
body[k] = []string{v}
logger.Debug("build form data ok.")
}
}
data := strings.NewReader(body.Encode())
logger.Debugf("url: %s, req: %+v", urlstr, data)
err = SendRequest(urlstr, "POST", "application/x-www-form-urlencoded", data, responseData)
if err != nil {
return err
}
return nil
}
4励堡、application/form-data格式
func PostFormDataRequest(urlstr string, requestData map[string]string, responseData interface{}) error {
var err error
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
if requestData != nil {
for k, v := range requestData {
err = writer.WriteField(k, v)
if err != nil {
err = fmt.Errorf("write form field %s:%s failed: %s", k, v, err.Error())
return err
}
logger.Debug("build form data ok.")
}
}
if err = writer.Close(); err != nil {
err = fmt.Errorf("close multipart form writer failed: %s", err.Error())
}
err = SendRequest(urlstr, "POST", writer.FormDataContentType(), body, responseData)
if err != nil {
return fmt.Errorf("do sendRequest error with param %s:%s", body, err.Error())
}
return nil
}
上述事例默認返回數(shù)據(jù)為json類型谷丸,這也是當(dāng)前 http接口最常用的信息交互數(shù)據(jù)格式。開發(fā)時可以根據(jù)實際的情況修改返回值處理邏輯应结。此外刨疼,請求方法類型也可以根據(jù)實際需求進行修改,如果請求方法類型不匹配將無法返回正確結(jié)果鹅龄。