长春比较有名的做网站建设,购物网站开发实例,网站入口设计,做门名片设计网站目录
写在前面
发送Post请求
示例代码
源码分析
Post请求参数解析
响应数据解析
验证
发送Json/XMl
Json请求示例代码
xml请求示例代码
总结
资料获取方法 写在前面
上一篇我们介绍了使用 net/http 发送get请求#xff0c;因为考虑到篇幅问题#xff0c;把Post单…目录
写在前面
发送Post请求
示例代码
源码分析
Post请求参数解析
响应数据解析
验证
发送Json/XMl
Json请求示例代码
xml请求示例代码
总结
资料获取方法 写在前面
上一篇我们介绍了使用 net/http 发送get请求因为考虑到篇幅问题把Post单独拎了出来我们在这一篇一起从源码来了解一下Golang的Post请求。 发送Post请求
net/http发送Post请求很容易下面的代码我们和Get请求一样把响应的内容的信息打印出来了细心的朋友可能会发现在参数传递、和结果解析时用了三种不同的方式我们将在后面进行解析。
示例代码
package mainimport (bytesfmtio/ioutilnet/httpreflectstrings
)func main() {resp, err : http.Post(http://httpbin.org/post,application/x-www-form-urlencoded,strings.NewReader(nameDetectormobile1xxxxxxxx))if err ! nil {fmt.Println(err)return}defer resp.Body.Close()headers : resp.Header// headers 打印报文头部信息for k, v : range headers {fmt.Printf(%v, %v\n, k, v) // %v 打印interfac{}的值}// 打印响应信息内容fmt.Printf(响应状态%s,响应码 %d\n, resp.Status, resp.StatusCode)fmt.Printf(协议%s\n, resp.Proto)fmt.Printf(响应内容长度 %d\n, resp.ContentLength)fmt.Printf(编码格式%v\n, resp.TransferEncoding) // 未指定时为空fmt.Printf(是否压缩%t\n, resp.Uncompressed)fmt.Println(reflect.TypeOf(resp.Body)) // *http.gzipReaderfmt.Println(resp.Body)buf : bytes.NewBuffer(make([]byte, 0, 512))length, _ : buf.ReadFrom(resp.Body)fmt.Println(len(buf.Bytes()))fmt.Println(length)fmt.Println(string(buf.Bytes()))body, err : ioutil.ReadAll(resp.Body)if err ! nil {fmt.Println(err)return}fmt.Println(string(body))
}源码分析
Post请求参数解析
我们首先来看一下C:\Go\src\net\http\client.go中Post和Get请求的源码
func Get(url string) (resp *Response, err error) {return DefaultClient.Get(url)
}func Post(url string, contentType string, body io.Reader) (resp *Response, err error) {return DefaultClient.Post(url, contentType, body)
}从上面的定义可以看出Post请求的参数比Get复杂一些不仅要传递string类型contentType还有传递io.Reader类型的body体。可能有的小伙伴就有疑问了-- io.Reader类型的body体是不是意味着我们一定要使用io.Reader模块来获取数据呢
答案当然是否定的。
我们通过阅读源码来找想要的答案。
找到其最小粒度的接口是一个比较好的手段io.Reader最小粒度的接口的定义在C:\Go\src\io\io.go中
type Reader interface {Read(p []byte) (n int, err error)
}在我前面的一篇博客【Golang】基础10 Go语言最精妙的设计--interface中学习过 interface其中有两句话是这样的 interface类型定义了一组方法如果某个对象实现了某个接口的所有方法则此对象就实现了此接口。如果我们定义了一个interface的变量那么这个变量里面可以存实现这个interface的任意类型的对象。 针对io.Reader的定义翻译一下就是只要实现了Read(p []byte) (n int, err error)方法的类型,就可以存储io.Reader从而作为Post请求的Body参数。
我们接着来看看响应resp中数据的定义。
响应数据解析
在上一篇我们对http请求中的数据进行了介绍这一次我们针对resp.Body进行展开。
在C:\Go\src\net\http\response.go中我们可以看到它的类型Body io.ReadCloser在C:\Go\src\io\io.go中我们可以看到对应的定义是这样的
type ReadCloser interface {ReaderCloser
}而Reader就是我们上面分析的过的请求body定义的Reader而Closer是一个error类型
type Closer interface {Close() error
}根据我们上面的结论-- 定义的某个接口的变量可以存储同样实现该接口的任意类型对象即是说任意类型只要实现了 Reader和 Closer 即可以用来解析resp.Body。
那我们来验证一下示例里面使用的三种方法是不是符合我们这个结论。
验证 strings.NewReader 我们可以在C:\Go\src\strings\reader.go看到 Reader类型的 Read方法 bytes.NewBuffer 我们可以在C:\Go\src\bytes\buffer.go看到 Buffer类型的 Read方法 ioutil.ReadAll 我们可以在C:\Go\src\io\ioutil\ioutil.go看到 io.Reader类型的 ReadAll和Close() error方法 发送Json/XMl
在了解了上面的知识之后我们再来看发送Json、XML数据等就比较简单了。
Json请求示例代码
func JsonReq() {info : make(map[string]interface{})info[name] Detectorinfo[age] 15info[loc] 深圳// 将map解析未[]byte类型bytesData, _ : json.Marshal(info)// 将解析之后的数据转为*Reader类型reader : bytes.NewReader(bytesData)println(reader)resp, _ : http.Post(http://httpbin.org/post,application/json,reader)body, _ : ioutil.ReadAll(resp.Body)fmt.Println(string(body))
}代码里面给了一些注释我们把要发送的数据转化为了 *Reader类型然后就可以直接发送了。我们从上面的源码分析可以知道这个类型是可以存储io.Reader的数据的
xml请求示例代码
func XMLReq() {xml : ?xml version1.0 encodingUTF-8?resourcesstring nameVideoLoadingLoading video…/stringstring nameApplicationNamewhat/string/resourcesbytesData : strings.NewReader(xml)resp, _ : http.Post(http://httpbin.org/post,application/xml,bytesData)body, _ : ioutil.ReadAll(resp.Body)fmt.Println(string(body))
}总结
Json、xml请求请求、响应数据简析interface概念复习 资料获取方法
【留言777】 各位想获取源码等教程资料的朋友请点赞 评论 收藏三连
三连之后我会在评论区挨个私信发给你们~