几种常用内容类型(Content-Type)的http客户端开发实例
在开发过程中,通常会遇到与其他服务做信息交换的情况,大多数情况下会通过http接口实现信息的交换。但是不同的服务接口指定的Content-Type类型是不同的。下文将通过实际的例子展示,常用的集中内容类型的http请求如何开发。
Content-Type(内容类型),一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些 PHP 网页点击的结果却是下载一个文件或一张图片的原因。
Content-Type 标头告诉客户端实际返回的内容的内容类型。s
http支持的Content-Type种类很多,但是实际中常用的主要有三种:application/x-www-form-urlencoded,application/form-data,application/json。
1、一个通用的请求方法
var httpTr = &http.Transport{
//控制主机的最大空闲连接数,0为没有限制
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
//长连接在关闭之前,保持空闲的最长时间,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))
// 解析响应
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
}
上述事例默认返回数据为json类型,这也是当前 http接口最常用的信息交互数据格式。开发时可以根据实际的情况修改返回值处理逻辑。此外,请求方法类型也可以根据实际需求进行修改,如果请求方法类型不匹配将无法返回正确结果。