近来无事,本着爱折腾的原则,在go原生 http client 的基础上,自己封装了一个go的http client。由于才疏学浅,再加是第一次造轮子,在各位大佬面前献丑了,写的烂的地方,请轻喷。还请各位不吝赐教。
先放地址
gethub: https://github.com/lqxhub/easy_http
Gitee: https://gitee.com/lqxlucky/easy_http
简单介绍一下功能
- 使用 构造器模式,提供了链式调用和方便使用的接口
- 支持https自定义服务器证书校验和双向证书校验
- 支持代理,可以方便的设置代理
- 封装了multipart 协议, 可以方便的上传文件
- 具有很强的拓展性,可以在基础上非常方便的定制自己http请求
- 支持http的 返回结果 异步回调
- 可以方便的自定义Response
安装库
可以使用github的库,也可使用Gitee的库,两个库的代码都是一样的,因为github网速的原因,所以在gitee上也传了一份
github:
go get -u https://github.com/lqxhub/easy_http
gitee:
go get -u https://gitee.com/lqxlucky/easy_http
使用
引入库
因为github和gitee拉下来的库目录不同,所以以github的为准
1import "github.com/lqxhub/easy_http"
具体使用
全部配置
1func main() {
2 //得到一个http client的构造器
3 builder := easy_http.NewClientBuilder()
4
5 //是否跳过服务器证书校验
6 builder.SkipVerify(false)
7
8 //设置超时时间
9 builder.TimeOut(time.Second * 5)
10
11 //设置代理
12 builder.ProxyUrl("http://127.0.0.1:10809")
13
14 //设置根证书
15 var certPool [1]string
16 certPool[0] = "D:\\server.pem"
17 builder.Cert(certPool[:])
18
19 //设置双向校验证书
20 var tlsPath [1]*easy_http.TlsPath
21 tlsPath[0] = &easy_http.TlsPath{
22 CertFile: "D:\\client.pem",
23 KeyFile: "D:\\client.key",
24 }
25 builder.Tls(tlsPath[:])
26
27 //设置http请求header
28 header := make(map[string]string)
29 header["Accept-Language"] = "Accept-Language: en,zh"
30 builder.Header(header)
31
32 //设置http请求cookie
33 cookie := make(map[string]string)
34 cookie["name"] = "value"
35 builder.Cookie(easy_http.EasyCookie(cookie))
36
37 //开启cookie jar
38 builder.Jar(nil)
39
40 //设置 Response 处理函数
41 builder.BuildResponse(easy_http.EasyBuildResponse)
42
43 //构造client
44 client, err := builder.Build()
45 if err != nil {
46 fmt.Println("aa", err)
47 return
48 }
49}
这样就初始化一个http的客户端
当然,上面的例子是设置了所有配置的,也可以全部使用默认配置
使用默认配置
1func DefaultClient() {
2 builder := easy_http.NewClientBuilder()
3 client, err := builder.Build()
4 if err != nil {
5 fmt.Println(err)
6 return
7 }
8 client.Get("http://baidu.com")
9}
这样同样是可以的
easy 函数 使用
库中提供了一些函数,可以方便的构造http请求相关的结构
1func EasyFunction() {
2
3 url := "http://baidu.com"
4
5 //合成http get的url和参数
6 values := make(map[string]string)
7 values["v"] = "123456"
8 easy_http.EasyGet(url, values)
9
10 //构造cookie
11 cookie := make(map[string]string)
12 cookie["name"] = "value"
13 easy_http.EasyCookie(cookie)
14
15 //合成 http post 的参数
16 easy_http.EasyPost(values)
17
18 //构造 上传文件的multipart
19 multipartBuilder := easy_http.NewMultipartBuilder()
20 multipartBuilder.AddFile("file1","D:\\a.txt")
21 multipartBuilder.AddFromDate("name","value")
22 multipartBuilder.AddBytes("name2",[]byte("aaaaa"))
23 multipart, err := multipartBuilder.Builder()
24
25}
异步回调使用
库封装了 异步回调功能,请求会在一个新的goroutine中进行。当http请求完成时,会回调函数。回调函数可用形参使用传入函数和实现接口两种方式
1
2func Call(response easy_http.IResponse) {
3 fmt.Println(response.Error())
4 fmt.Println(response.StatusCode())
5 fmt.Println(string(response.Content()))
6}
7
8type Get struct {
9}
10
11func (g Get) EasyResponseCallback(response easy_http.IResponse) {
12 fmt.Println(response.Error())
13 fmt.Println(response.StatusCode())
14 fmt.Println(string(response.Content()))
15}
16
17func AsynchronousRequest() {
18 url := "http://baidu.com"
19 client, err := easy_http.NewClientBuilder().Build()
20 if err != nil {
21 fmt.Println(err)
22 return
23 }
24
25 //函数异步回调
26 client.GetAsyn(url, Call)
27
28 //接口异步回调
29 client.GetAsynWithCallback(url, &Get{})
30}
自定义请求
因为库中只封装了 GET和POST这两种方式,向PUT,DELETE等这些方式需要自己去实现。所以,可以使用下面的函数来实现
1func Call(response easy_http.IResponse) {
2 fmt.Println(response.Error())
3 fmt.Println(response.StatusCode())
4 fmt.Println(string(response.Content()))
5}
6
7func CustomizeRequest() {
8 url := "http://baidu.com"
9 client, err := easy_http.NewClientBuilder().Build()
10 if err != nil {
11 fmt.Println(err)
12 return
13 }
14 response := client.SendWithMethod(url, http.MethodPut, nil, func(request *http.Request) {
15 //修改Request
16 })
17 fmt.Println(response.Error())
18 fmt.Println(response.StatusCode())
19
20 //异步方式
21 client.SendWithMethodCallBack(url, http.MethodPut, nil, func(request *http.Request) {
22 //习惯Request
23 }, Call)
24}
使用go http默认的函数请求
当需要有一些特殊的请求,这个库无法满足时,可以使用go http原生的方式来请求
1func Primitive() {
2 url := "http://baidu.com"
3 client, err := easy_http.NewClientBuilder().Build()
4 if err != nil {
5 fmt.Println(err)
6 return
7 }
8 //获取Request
9 request, err := http.NewRequest(http.MethodGet, url, nil)
10 if err != nil {
11 fmt.Println(err)
12 return
13 }
14 //得到http的原生Response
15 response, err := client.DoRequest(request)
16 if err != nil {
17 fmt.Println(err)
18 return
19 }
20 fmt.Println(response)
21}
自定义Response
库中返回的Response是一个接口类型,只要实现了这个接口,都可作为返回值返回,自定义的Response,在构造client的设置就可以了
1type MyResponse struct {
2}
3
4func (m MyResponse) Error() error {
5 return nil
6}
7
8func (m MyResponse) StatusCode() int {
9 return 0
10}
11
12func (m MyResponse) Header() http.Header {
13 return nil
14}
15
16func (m MyResponse) ContentLength() int64 {
17 return 0
18}
19
20func (m MyResponse) Content() []byte {
21 return nil
22}
23
24func (m MyResponse) Resp() *http.Response {
25 return nil
26}
27
28func (m MyResponse) Request() *http.Request {
29 return nil
30}
31
32func (m MyResponse) Cookie(name string) *http.Cookie {
33 return nil
34}
35
36//构造HTTP response的函数
37func MyBuildResponse(resp *http.Response, err error) easy_http.IResponse {
38 response := new(MyResponse)
39 //做处理
40 return response
41}
42func CustomizeResponse() {
43 client, err := easy_http.NewClientBuilder().
44 BuildResponse(MyBuildResponse).
45 Build()
46 if err != nil {
47 fmt.Println(err)
48 return
49 }
50}
结构体 MyResponse
实现了 easy_http.IResponse
这个接口。然后在MyBuildResponse
这个函数中,new 一个 MyResponse
的对象,再根据自己的需要,做相应的处理就可以了。
在clientBuilder.BuildResponse(MyBuildResponse)
设置就可以了
最后
整个库的基本功能就是这些了。第一造轮子,写的很烂。写这篇文章时,还发现了好几个因为首字母小写导致的问题。
有问题的地方,还请不吝赐教