背景:突然有一天,我需要写一个接口给前端同学使用,这个接口是要给第三方接口发送一个网络请求,于是我遍开始从零到一的完成了这个接口。
具体实现
id
//首先,声明一个结构体,根据此结构体创建的对象用来绑定GET请求发送的参数
//补充:gin框架中一般都是把传递来的参数给绑定到接结构体中,结构体的定义也是根据参数的名称和类型的定义的
type ResponseCheckOnline struct {
HornId string `form:"id"`
HornToken string `header:"token"`//token是存放在header中的,所以此处要打上header的标签
}
//声明一个对象
var req ResponseCheckOnline
//接下来开始参数绑定
c.ShouldBind(&req) //由于我们发送的是一个get请求,所以我们不能使用ShouldBindJson方法,我们应该使用ShouldBind函数,并且需要在结构体后面打上form标签,注意一定要打上from标签,对于GET请求的参数对应的结构体,如果打上的是json标签,那是无法绑定的(此函数功能十分强大,后面补充详细的内容)
//上面绑定的是url中的param参数,不要忘记,我们还有一个参数是在header请求头里面的,我们也需要拿到这个参数绑定到结构体中
c.ShouldBindHeader(&req)//最初在这个地方产生了疑惑,后面百度接口,我们使用此方法的同时,需要的上面的结构体中加入header标签(参考博客:https://blog.csdn.net/wohu1104/article/details/121928193)
//这是参数校验,如果为空就是没绑定上,我们应该返回错误提示
if req.HornId == "" || req.HornToken == "" {
global.GVA_LOG.Error("通过喇叭id和token判断喇叭是否在线参数错误")
return
}
//开始请求第三方接口判断喇叭是否在线,需要发送请求给第三方接口
// 创建各类对象
var client *http.Client
var request *http.Request
var resp *http.Response
var body []byte
//`这里请注意,使用 InsecureSkipVerify: true 来跳过证书验证`
client = &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}, Timeout: time.Duration(utils.TimeOut) * time.Millisecond}
url := "http://xxx?id=" + req.HornId
request, err := http.NewRequest(http.MethodGet, url, nil)//创建一个请求,第一个参数是请求类型,第二个参数是请求地址,第三个不太了解,好像是请求携带的一些东西吧,可以自行百度一下,此处填写nil即可
if err != nil {
log.Println("GetHttpSkip Request Error:", err)
return
}
//加入 token,需要添加到header请求头中
request.Header.Add("token", req.HornToken)
//发送请求
resp, err = client.Do(request)
if err != nil {
global.GVA_LOG.Error(fmt.Sprintf("查看喇叭状态失败,喇叭id:%s", req.HornId), zap.Error(err))
return
}
defer resp.Body.Close()
//读取返回的结果
body, err = ioutil.ReadAll(resp.Body)
//把结果绑定到到对象上面并反序列化为json类型
data := new(appRes.CheckOnlineRes)
err = json.Unmarshal(body, data)
fmt.Println(data.DeviceStatus)
defer resp.Body.Close()
if err == nil {
response.OkWithDetailed(data, "查看摄像头状态成功", c)
} else {
response.FailWithDetailed(nil, "查看摄像头状态失败", c)
}
//此结构体后面的json标签都是需要根据我们此接口请求的第三方接口返回来的字段来定义的,如果和第三方接口返回的字段不一致,将无法成功绑定
type CheckOnlineRes struct {
Code int `json:"code"` //状态码
Msg string `json:"msg"` //请求状态信息
CheckOnlineResData `json:"data"` //摄像头是否在线,1 正常 2掉线 3禁用
}
//此结构体被上面结构体引用,定义此结构体的原因是第三方接口返回的第三个参数是一个数据类型的数据,有10余个,而我们只需要拿到一个即可
type CheckOnlineResData struct {
DeviceStatus string `json:"deviceStatus"`
}
补充:c.shouldBind()函数
POSTcontent-typeJSONXMLFormform-data
Form
同时也可以绑定form表单参数。
说在最后,gin框架的参数大多都是绑定到结构体对象上,这些方法gin都已经实现好了,我们可以拿现成的方法来用,但是处理不同请求的不同类型的参数的时候,有一些要求,这些要求比较琐碎,比较容易忽略,从而导致参数绑定出现问题,所以再绑定参数到结构体上面时,我们需要心思细腻一点。