Golang?Gin框架獲取請(qǐng)求參數(shù)的幾種常見(jiàn)方式
傳遞參數(shù)的方式
在一個(gè)HTTP請(qǐng)求中,一般可以把上傳參數(shù)分為以下三個(gè)部分:
Header
Header是HTTP請(qǐng)求中一個(gè)鍵值對(duì)集合,HTTP規(guī)范定義了很多的Headeer,比如Content-Type,Accept等,不過(guò)也可以自定義請(qǐng)求頭部或者響應(yīng)頭部。
URL
URL指的是請(qǐng)求路徑,在請(qǐng)求路徑上可以通過(guò)兩種方式攜帶請(qǐng)求參數(shù),一種是直接寫在請(qǐng)求路徑上的,稱為URL Path:
http://localhost:8080/user/add
在URL上傳遞參數(shù)的另外一種方式就是URL Query,URL Query參數(shù)是指跟在?后面的鍵值對(duì)集合,多個(gè)參數(shù)之間以&分隔的:
http://localhost:8080/user/add?name=小明&gender=男
HTTP Body
HTTP Body參數(shù)是指HTTP請(qǐng)求的請(qǐng)求體所攜帶的參數(shù),這部分參數(shù)會(huì)因?yàn)镃ontent-Type不同而不同,比如當(dāng)Content-Type為application/json時(shí),HTTO Body攜帶的是一串JSON字符串。
那么,在Gin框架中,要如何獲取這些請(qǐng)求參數(shù)呢?主要有以下兩種方式:
- 直接用Gin封裝的方法獲取請(qǐng)求參數(shù)
- 通過(guò)綁定的方式來(lái)獲取請(qǐng)求參數(shù)
直接獲取請(qǐng)求參數(shù)
Gin框架在net/http包的基礎(chǔ)上封裝了獲取參數(shù)的方式。
獲取URL Path中的參數(shù)
在路由中使用通配符時(shí),對(duì)應(yīng)的通配符就會(huì)成為URL Path參數(shù),調(diào)用gin.Context的Param()方法可以獲取Path參數(shù):
package main ? func main(){ engine := gin.Default() engine.GET("/user/:id", func(ctx *gin.Context) { id := ctx.Param("id") fmt.Fprintf(ctx.Writer, "你的請(qǐng)求id:%s", id) }) engine.Run() }
運(yùn)行后發(fā)起請(qǐng)求:
$ curl http://localhost:8080/user/100 你的請(qǐng)求id:100
獲取URL Query中的參數(shù)
gin.Context對(duì)象提供了以下幾個(gè)主要方法用于獲取Query參數(shù):
package main ? import ( "fmt" ? "github.com/gin-gonic/gin" ) ? func main() { engine := gin.New() engine.GET("/user/list", func(ctx *gin.Context) { //獲取單個(gè)值 name := ctx.Query("name") //帶默認(rèn)值 gender := ctx.DefaultQuery("gender", "男") //數(shù)組 habits := ctx.QueryArray("habits") //map works := ctx.QueryMap("works") fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works) }) ? engine.Run() }
行后發(fā)起請(qǐng)求:
curl -X GET "http://localhost:8080/user/list?name=John&gender=男&habits[]=reading&habits[]=sports&works[teacher]=math&works[engineer]=computer" John,男,[reading sports],map[engineer:computer teacher:math]
獲取HTTP Body中的參數(shù)
對(duì)于通過(guò)HTTP Body傳上來(lái)的參數(shù),gin.Context也提供了幾種主要方法用于獲取:
package main ? import ( "fmt" ? "github.com/gin-gonic/gin" ) ? func main() { engine := gin.New() engine.POST("/user/add", func(ctx *gin.Context) { //獲取單個(gè)值 name := ctx.PostForm("name") //帶默認(rèn)值 gender := ctx.DefaultPostForm("gender", "男") //數(shù)組 habits := ctx.PostFormArray("habits") //map works := ctx.PostFormMap("works") fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works) }) ? engine.Run() }
綁定請(qǐng)求參數(shù)
Gin支持綁定Header,URL Path,URL Query以及HTTP Body等不同位置數(shù)據(jù)。
綁定Header參數(shù)
綁定Header參數(shù)可以使用BindHeader()或者ShouldBindHeader()方法:
package main ? import ( "fmt" "net/http" ? "github.com/gin-gonic/gin" ) ? type testHeader struct { Rate int `header:"Rate"` Domain string `header:"Domain"` } ? func main() { r := gin.Default() r.GET("/", func(c *gin.Context) { h := testHeader{} ? if err := c.ShouldBindHeader(&h); err != nil { c.JSON(http.StatusBadRequest, err) return } ? fmt.Printf("%#v\n", h) c.JSON(http.StatusOK, gin.H{"Rate": h.Rate, "Domain": h.Domain}) }) ? r.Run() }
運(yùn)行后的請(qǐng)求結(jié)果:
$ curl -H "rate:300" -H "test:123" http://localhost:8080/ {"Test":"123","Rate":300}
綁定URL Path參數(shù)
綁定URL Path參數(shù)可以使用BindUri()或者ShouldBindUri()方法:
package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) type User struct { Name string `uri:"name"` Email string `uri:"email"` } func main() { engine := gin.New() engine.GET("/user/list/:email/:name", func(ctx *gin.Context) { var u User if err := ctx.BindUri(&u);err != nil { ctx.JSON(http.StatusBadRequest, err) return } fmt.Fprintf(ctx.Writer, "你輸入的用戶名為:%s,郵箱為:%s\n", u.Name, u.Email) }) engine.Run() }
運(yùn)行后的請(qǐng)求結(jié)果:
curl -X GET "http://localhost:8080/user/list/john@163.com/john 你輸入的用戶名為:john,郵箱為:john@163.com
綁定URL Query參數(shù)
綁定URL Query參數(shù)可以使用BindQuery()、ShouldBindQury()、Bind()或者ShouldBind()方法:
package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) type User struct { Name string `form:"name"` Email string `form:"email"` } func main() { engine := gin.New() engine.GET("/user/list", func(ctx *gin.Context) { var u User if err := ctx.BindQuery(&u);err != nil { ctx.JSON(http.StatusBadRequest, err) return } fmt.Fprintf(ctx.Writer, "你輸入的用戶名為:%s,郵箱為:%s\n", u.Name, u.Email) }) engine.Run() }
運(yùn)行后的請(qǐng)求結(jié)果:
curl -X GET "http://localhost:8080/user/list?email=john@163.com&name=john 你輸入的用戶名為:john,郵箱為:john@163.com
綁定HTTP Body參數(shù)
我們知道HTTP Body的參數(shù)會(huì)根據(jù)不同Content-Type傳不同格式的數(shù)據(jù),Gin支持以下幾種Content-Type類型的綁定:
- JSON
- XML
- TOML
- YAML
- x-www-form-urlencoded
- multipart/form-data
注意HTTP Body的數(shù)據(jù)只在POST請(qǐng)求時(shí)才會(huì)進(jìn)行綁定。
綁定HTTP Body參數(shù)可以用Bind()和ShouldBind()方法,這兩個(gè)方法會(huì)根據(jù)當(dāng)前請(qǐng)求的Content-Type類型自動(dòng)判斷請(qǐng)求的類型。
package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) type User struct { Name string Email string } func main() { engine := gin.New() engine.POST("/user/add", func(ctx *gin.Context) { var u User if err := ctx.Bind(&u); err != nil { ctx.JSON(http.StatusBadRequest, err.Error()) return } fmt.Fprintf(ctx.Writer, "你輸入的用戶名為:%s,郵箱為:%s\n", u.Name, u.Email) }) engine.Run() }
如果明確請(qǐng)求數(shù)據(jù)的類型,也可以直接調(diào)用對(duì)應(yīng)類型綁定的方法,比如確定是JSON格式數(shù)據(jù)的話,可以調(diào)用BindJSON()或者ShouldBindJSON():
package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) type User struct { Name string Email string } func main() { engine := gin.New() engine.POST("/user/add", func(ctx *gin.Context) { var u User if err := ctx.BindJSON(&u); err != nil { ctx.JSON(http.StatusBadRequest, err.Error()) return } fmt.Fprintf(ctx.Writer, "你輸入的用戶名為:%s,郵箱為:%s\n", u.Name, u.Email) }) engine.Run() }
對(duì)于x-www-form-urlencoded和multipart/form-data,與Qurey參數(shù)一樣,結(jié)構(gòu)體需要添加form的tag:
package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) type User struct { Name string `form:"name"` Email string `form:"email"` } func main() { engine := gin.New() engine.POST("/user/add", func(ctx *gin.Context) { var u User if err := ctx.Bind(&u); err != nil { ctx.JSON(http.StatusBadRequest, err.Error()) return } fmt.Fprintf(ctx.Writer, "你輸入的用戶名為:%s,郵箱為:%s\n", u.Name, u.Email) }) engine.Run() }
數(shù)據(jù)校驗(yàn)
在數(shù)據(jù)綁定的時(shí)候,也可以進(jìn)行數(shù)據(jù)校驗(yàn),這里我們?yōu)閁ser結(jié)構(gòu)體的標(biāo)簽添加了required屬性,要求這個(gè)字段必須要有:
package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) type User struct { Name string `binding:"required"` Email string `binding:"required"` } func main() { engine := gin.New() engine.POST("/user/add", func(ctx *gin.Context) { var u User if err := ctx.Bind(&u); err != nil { ctx.JSON(http.StatusBadRequest, err.Error()) return } fmt.Fprintf(ctx.Writer, "你輸入的用戶名為:%s,郵箱為:%s\n", u.Name, u.Email) }) engine.Run() }
兩種方式的對(duì)比
相較于直接獲取請(qǐng)求參數(shù),請(qǐng)求數(shù)據(jù)綁定是一種更強(qiáng)大且優(yōu)雅的參數(shù)獲取方式,使用這種方式獲取參數(shù)有以下幾個(gè)好處:
- 直接將所有參數(shù)綁定到一個(gè)結(jié)構(gòu)體中,不需要手動(dòng)一個(gè)個(gè)地獲取參數(shù)。
- 綁定后的參數(shù)會(huì)自動(dòng)轉(zhuǎn)換為結(jié)構(gòu)體對(duì)應(yīng)字段的類型,不需要手動(dòng)對(duì)每個(gè)參數(shù)進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換。
- 在進(jìn)行數(shù)據(jù)綁定的同時(shí)還可以進(jìn)行數(shù)據(jù)校驗(yàn)。
小結(jié)
直接獲取請(qǐng)求參數(shù)雖然沒(méi)有綁定參數(shù)那么強(qiáng)大,但對(duì)于簡(jiǎn)單的請(qǐng)求來(lái)說(shuō),也是夠用的,因此,我們可以根據(jù)自己的需求,選擇對(duì)應(yīng)的方式來(lái)獲取請(qǐng)求參數(shù)。
以上就是Golang Gin框架獲取請(qǐng)求參數(shù)的幾種常見(jiàn)方式的詳細(xì)內(nèi)容,更多關(guān)于Golang Gin獲取請(qǐng)求參數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go實(shí)現(xiàn)List、Set、Stack、Deque等數(shù)據(jù)結(jié)構(gòu)的操作方法
Go語(yǔ)言團(tuán)隊(duì)的一個(gè)核心目標(biāo)是保持語(yǔ)言的簡(jiǎn)單性,他們認(rèn)為,如果一個(gè)功能可以用簡(jiǎn)單的組合來(lái)實(shí)現(xiàn),那就沒(méi)有必要把它放進(jìn)標(biāo)準(zhǔn)庫(kù)里,本文給大家介紹Go實(shí)現(xiàn)List、Set、Stack、Deque等數(shù)據(jù)結(jié)構(gòu)的操作方法,感興趣的朋友跟隨小編一起看看吧2024-12-12詳解Gotorch多機(jī)定時(shí)任務(wù)管理系統(tǒng)
遵循著“學(xué)一門語(yǔ)言最好的方式是使用它”的理念,想著用Go來(lái)實(shí)現(xiàn)些什么,剛好有一個(gè)比較讓我煩惱的問(wèn)題,于是用Go解決一下,即使不在生產(chǎn)環(huán)境使用,也可以作為Go語(yǔ)言學(xué)習(xí)的一種方式。2021-05-05Golang之casbin權(quán)限管理的實(shí)現(xiàn)
這篇文章主要介紹了Golang之casbin權(quán)限管理的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10golang組件swagger生成接口文檔實(shí)踐示例
這篇文章主要為大家介紹了golang組件swagger生成接口文檔實(shí)踐示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04