我們了解到gin可用通過類似DefaultQuery或DefaultPostForm等方法獲取到前端提交過來的參數(shù)。參數(shù)不多的情況下也很好用,但是想想看,如果接口有很多個(gè)參數(shù)的時(shí)候再用這種方法就要調(diào)用很多次獲取參數(shù)的方法,本文將介紹一種新的接收參數(shù)的方法來解決這個(gè)問題:模型綁定。
gin中的模型綁定可以理解為:把請(qǐng)求的參數(shù)映射為一個(gè)具體的類型。gin支持JSON,XML,YAML和表單參數(shù)等多種參數(shù)格式,只需要在對(duì)應(yīng)的字段上聲明標(biāo)簽。
綁定表單或者查詢字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
|
type Person struct { Name string `form: "name" ` Address string `form: "address" ` } func startPage(c *gin.Context) { var person Person if c.ShouldBindQuery(&person) == nil { log.Println(person.Name) log.Println(person.Address) } c.String(200, "Success" ) } |
在結(jié)構(gòu)體Name字段聲明form標(biāo)簽,并調(diào)用ShouldBindQuery方法,gin會(huì)為我們綁定查詢字符串中的name和address兩個(gè)參數(shù)。注意雖然我們聲明了form標(biāo)簽,ShouldBindQuery只綁定查詢字符串中的參數(shù)。
如果你想綁定表單中的參數(shù)的話結(jié)構(gòu)體不用改變,需要把ShouldBindQuery方更改為ShouldBind方法。ShouldBind方法會(huì)區(qū)分GET和POST請(qǐng)求,如果是GET請(qǐng)求綁定查詢字符串中的參數(shù),如果是POST請(qǐng)求綁定表單參數(shù)中的內(nèi)容,但是不能同時(shí)綁定兩種參數(shù)。
綁定json參數(shù)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
type Person struct { Name string `json: "name" ` Address string `json: "address" ` } func startPage(c *gin.Context) { var person Person if c.ShouldBind(&person) == nil { log.Println(person.Name) log.Println(person.Address) } c.String(200, "Success" ) } |
json是一種常用的數(shù)據(jù)交換格式,尤其是在和web前端頁面交互的時(shí)候,似乎已經(jīng)成為了一種事實(shí)標(biāo)準(zhǔn)。gin綁定json格式數(shù)據(jù)方法很簡單,只需要設(shè)置字段的標(biāo)簽為json并且調(diào)用ShouldBind方法。
其他類型參數(shù)綁定
路由參數(shù)在綁定時(shí)設(shè)置標(biāo)簽為uri,并調(diào)用ShouldBindUri方法。
1
2
3
4
5
6
7
8
9
10
11
|
type Person struct { Id string `uri: "id" ` } func startPage(c *gin.Context) { var person Person if c.ShouldBindUri(&person) == nil { log.Println(person.Id) } c.String(200, "Success" ) } |
綁定在HTTP Header中的參數(shù),字段的標(biāo)簽設(shè)置為header,調(diào)用方法為ShouldBindHeader。
還有不太常用的數(shù)組參數(shù)是字段標(biāo)簽設(shè)置為form:"colors[]",結(jié)構(gòu)體例子如下:
1
2
3
|
type myForm struct { Colors []string `form: "colors[]" ` } |
文件上傳這種場景我很少用模型綁定的方式獲取參數(shù),在gin中對(duì)于這種場景也提供了模型綁定支持。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
type ProfileForm struct { Name string `form: "name" ` Avatar *multipart.FileHeader `form: "avatar" ` // Avatars []*multipart.FileHeader `form:"avatar"` 多文件上傳 } func main() { router := gin.Default() router.POST( "/profile" , func(c *gin.Context) { var form ProfileForm if err := c.ShouldBind(&form); err != nil { c.String(http.StatusBadRequest, "bad request" ) return } err := c.SaveUploadedFile(form.Avatar, form.Avatar.Filename) if err != nil { c.String(http.StatusInternalServerError, "unknown error" ) return } c.String(http.StatusOK, "ok" ) }) router.Run( ":8080" ) } |
多種類型的模型綁定
如果我們有一個(gè)UpdateUser接口,PUT /user/:id,參數(shù)是{"nickname": "nickname...","mobile": "13322323232"}。代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
type ProfileForm struct { Id int `uri: "id" ` Nickname string `json: "nickname" ` // 昵稱 Mobile string `json: "mobile" ` // 手機(jī)號(hào) } func main() { router := gin.Default() router.GET( "/user/:id" , func(c *gin.Context) { var form ProfileForm if err := c.ShouldBindUri(&form); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error" : err.Error()}) return } if err := c.ShouldBindJSON(&form); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error" : err.Error()}) return } c.String(http.StatusOK, "ok" ) }) router.Run( ":8080" ) } |
代碼里調(diào)用了兩次bind方法才獲取到全部的參數(shù)。和gin社區(qū)溝通之后發(fā)現(xiàn)目前還不能調(diào)用一個(gè)方法同時(shí)綁定多個(gè)參數(shù)來源,當(dāng)前gin版本為1.6.x,不知道未來會(huì)不會(huì)提供這種功能。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://www.cnblogs.com/huaface/p/13890194.html