今天继续深入往下讲,上一篇咱们对http的客户端设置进行了结构化统一,现在咱们开始对http请求进行结构化统一,首先咱们梳理http请求包含的结构。
代码语言:javascript复制http需要:
1. 接口名称,比如:登录接口
2. 接口方法,比如:get、post
3. 请求url, 比如:http://www.baidu.com
4. 请求头, 比如:token:******, content-type: ****
5. 请求query,比如:get请求中http://****/index?detail=1&id=2&name=3
6. 请求cookie, 比如:cookie:******
7. 请求body, 也就是请求体
8. http客户端设置项
根据以上列出的结构,我们在model/http_model.go文件中新增如下结构体:
代码语言:javascript复制// HttpRequest http请求的结构
type HttpRequest struct {
Name string // 接口名称
Url string // 接口uri
Method string // 接口方法,Get Post Update...
Headers []Header // 接口请求头
Querys []Query // get请求时的url
Cookies []Cookie // cookie
Body string // 请求体
HttpClientSettings HttpClientSettings // http客户端配置
}
// Header header
type Header struct {
Field string // 字段名称
Value string // 字段值
FieldType string // 字段类型
}
// Query query
type Query struct {
Field string
Value string
FieldType string
}
// Cookie cookie
type Cookie struct {
Field string
Value string
FieldType string
}
同时,我们讲http_client.go从server目录移动到新建的client目录下,并修改RequestHttp()方法,首先将入参由HttpClientSettings结构体变成HttpRequest结构体。并设置相应的接口方法、header、query、cookie以及url,结果如下:
代码语言:javascript复制func RequestHttp(httpModel model.HttpRequest) {
// 使用fasthttp 协程池
// 新建一个http请求
req := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(req)
// 新建一个http响应接受服务端的返回
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(resp)
// 新建一个http的客户端, newHttpClient是一个方法,在下面
client := newHttpClient(httpModel.HttpClientSettings)
// 添加该请求的http方法:get、post、delete、update等等
req.Header.SetMethod(httpModel.Method)
// 设置header
for _, header := range httpModel.Headers {
if strings.EqualFold(header.Field, "host") {
// 由于在header中设置host不生效,所以需要强制设置生效
req.SetHost(header.Value)
req.UseHostHeader = true
} else {
req.Header.Add(header.Field, header.Value)
}
}
// 设置cookie
for _, cookie := range httpModel.Cookies {
req.Header.SetCookie(cookie.Field, cookie.Value)
}
// 如果query不为空则设置query
urlQuery := req.URI().QueryArgs()
for _, query := range httpModel.Querys {
if !strings.Contains(httpModel.Url, query.Field) {
queryBy := []byte(query.Value)
urlQuery.AddBytesV(query.Field, queryBy)
httpModel.Url = fmt.Sprintf("&%s=%s", query.Field, query.Value)
}
}
req.SetBody([]byte(httpModel.Body))
// 添加该请求的http的url
req.SetRequestURI(httpModel.Url)
// 记录开始时间
startTime := time.Now()
// 开始请求
err := client.Do(req, resp)
// 计算响应时间差值
requestTime := time.Since(startTime)
if err != nil {
fmt.Sprintln("发送http请求错误:", err.Error())
}
// 以毫秒打印
fmt.Println("请求响应时间为:", requestTime.Milliseconds())
fmt.Println("header: ", string(req.Header.Header()))
fmt.Println("req: ", string(req.Body()))
fmt.Println("resp: ", string(resp.Body()))
}
然后,修改main.go中的main方法:
代码语言:javascript复制package main
import (
"kitchen-engine/client"
"kitchen-engine/model"
)
func main() {
// 一个类型中的字段,可以重置,也可以使用默认值,在go中,所有的类型的初始值,都是字段类型的0值,比如string的初始值是""空字符串,int类型的初始值是0等等
httpClientSettings := model.HttpClientSettings{
Name: "测试厨房",
NoDefaultUserAgentHeader: true,
MaxConnDuration: 1000,
}
headers := []model.Header{
model.Header{
Field: "name",
Value: "你好",
},
}
httpRequest := model.HttpRequest{
Name: "planet",
Url: "http://www.baidu.com",
Method: "GET",
HttpClientSettings: httpClientSettings,
Headers: headers,
}
client.RequestHttp(httpRequest)
}
运行,打印结果如下:
代码语言:javascript复制GOROOT=D:workToolsGO #gosetup
GOPATH=C:Users13383go #gosetup
D:workToolsGObingo.exe build -o C:Users13383AppDataLocalTempGoLand___go_build_kitchen_engine.exe kitchen-engine #gosetup
C:Users13383AppDataLocalTempGoLand___go_build_kitchen_engine.exe
req: GET / HTTP/1.1
User-Agent: 测试厨房
Host: www.baidu.com
ok,到此基本完成了http请求的配置,其他高级选项,在下章节讲述。