Gin 框架 -六-: 參數綁定
1. 介紹
在Gin
框架中參數不但能通過指定key
接收, 也可以直接綁定到結構體中, 本篇主要講解怎麼直接綁定到結構體中, 若要查看通過指定key
接收,可查看歷史文章 Gin 框架 (五): 參數接收;
1.1 綁定方法
Gin
提供了Must bind 和 Should bind
兩種類型的綁定方法,這兩種類型對應的方法如下:
a.MustBindWith和ShouldBindWith
Bind*
類型的方法是對MustBindWith
封裝;Should*
類型的方法是對ShouldBindWith
的封裝;
1.2 綁定語法
定義被綁定的結構體
type StructName struct {
Xxx type `form:"paramName" binding:"required"`
}
標籤說明:
-
form:"paramName"
:paramName
爲參數的名稱; -
binding:"required"
: 代表字段必須綁定;
2. 綁定 uri 參數
通過使用函數BindQuery
和ShouldBindQuery
,用來只綁定GET
請求中的uri
參數,如:/funcName?a=x&b=x中的a和b
。
2.1 代碼
//-------- main.go ---------------
package main
import (
"github.com/gin-gonic/gin" // 引入Gin框架
"go-use/practise" // 代碼示例包
)
func main() {
engine := gin.Default()
practise.TestBindQuery(engine)
_ = engine.Run()
}
//------ go-use/practise/param_bind.go -------
// 定義結構體
type UriParam struct {
Name string `form:"name" binding:"required"`
Age int `form:"age"`
Home string `form:"home"`
}
// 綁定GET(BindQuery和ShouldBindQuery)
func TestBindQuery(engine *gin.Engine) {
engine.GET("/bindQuery", func(context *gin.Context) {
bindType := context.Query("type")
var uriParam UriParam
var err error
if bindType == "1" {
fmt.Println("BindQuery")
err = context.BindQuery(&uriParam)
} else {
fmt.Println("ShouldBindQuery")
err = context.ShouldBindQuery(&uriParam)
}
if err != nil {
context.JSON(500, gin.H{"error": err.Error()})
return
}
fmt.Printf("uriParam:%+v\n", uriParam)
context.JSON(200, gin.H{"result": uriParam})
})
}
2.2 請求
# 參數都傳
➜ curl -X GET http://127.0.0.1:8080/bindQuery?age=24&name=張三&home=北京&type=1
{"result":{"Name":"張三","Age":24,"Home":"北京"}}
➜ curl -X GET http://127.0.0.1:8080/bindQuery?age=24&name=張三&home=北京&type=2
{"result":{"Name":"張三","Age":24,"Home":"北京"}}
# 必填參數name不填時,都會報錯
➜ curl -X GET http://127.0.0.1:8080/bindQuery?age=24&home=北京&type=2
{"error":"Key: 'UriParam.Name' Error:Field validation for 'Name' failed on the 'required' tag"}
3. 綁定 JSON
使用函數BindJSON 和 ShouldBindJSON
來綁定提交的JSON
參數信息。
3.1 代碼
//-------- main.go ---------------
package main
import (
"github.com/gin-gonic/gin" // 引入Gin框架
"go-use/practise" // 代碼示例包
)
func main() {
engine := gin.Default()
practise.TestBindJson(engine)
_ = engine.Run()
}
//------ go-use/practise/param_bind.go -------
// 定義待綁定的JSON結構體
type Param struct {
Name string `json:"name"`
Age int `json:"age"`
Likes []string `json:"likes"`
}
// 綁定提交的Json數據
func TestBindJson(engine *gin.Engine) {
engine.POST("/bindJson", func(context *gin.Context) {
var jsonParam Param
var err error
bindType := context.Query("type")
fmt.Println(bindType)
if bindType == "1" {
err = context.BindJSON(&jsonParam)
} else {
err = context.ShouldBindJSON(&jsonParam)
}
if err != nil {
context.JSON(500, gin.H{"error": err})
return
}
context.JSON(200, gin.H{"result": jsonParam})
})
}
3.2 請求
4. 綁定 XML
使用函數BindXML 和 ShouldBindXML
來綁定提交的XML
參數信息。
4.1 代碼
//-------- main.go ---------------
package main
import (
"github.com/gin-gonic/gin" // 引入Gin框架
"go-use/practise" // 代碼示例包
)
func main() {
engine := gin.Default()
practise.TestBindXml(engine)
_ = engine.Run()
}
//------ go-use/practise/param_bind.go -------
// 修改待綁定的JSON結構體,添加XML標籤
type Param struct {
Name string `json:"name" xml:"name"`
Age int `json:"age" xml:"age"`
Likes []string `json:"likes" xml:"likes"`
}
// 綁定Xml信息
func TestBindXml(engine *gin.Engine) {
engine.POST("/bindXml", func(context *gin.Context) {
var param Param
var err error
bindType := context.Query("type")
if bindType == "1" {
err = context.BindXML(¶m)
} else {
err = context.ShouldBindXML(¶m)
}
if err != nil {
context.JSON(500, gin.H{"error": err})
return
}
context.JSON(200, gin.H{"result": param})
})
}
4.2 請求
5. 綁定request.Body
c.Request.Body
不能多次被調用, 第一次綁定之後 c.Request.Body會設置成EOF
5.1 錯誤示例
a. 代碼
//-------- main.go ---------------
package main
import (
"github.com/gin-gonic/gin" // 引入Gin框架
"go-use/practise" // 代碼示例包
)
func main() {
engine := gin.Default()
practise.TestBindXml(engine)
_ = engine.Run()
}
//------ go-use/practise/param_bind.go -------
type BodyAParam struct {
Name string `json:"name"`
}
type BodyBParam struct {
Home string `json:"home"`
}
// 重複綁定request.Body(錯誤示例)
func TestBindBody(engine *gin.Engine) {
engine.POST("/body", func(context *gin.Context) {
paramA := BodyAParam{}
paramB := BodyBParam{}
// c.ShouldBind 使用了 c.Request.Body,不可重用。
_ = context.ShouldBindJSON(¶mA)
// 因爲現在 c.Request.Body 是 EOF,所以這裏會報錯。
_ = context.ShouldBindJSON(¶mB)
context.JSON(200,gin.H{"paramA":paramA,"paramB":paramB})
})
}
b. 請求返回
# 發現只有paramA綁定成功
➜ curl -X POST http://127.0.0.1:8080/body -d '{"name":"李四","home":"上海"}'
{"paramA":{"name":"李四"},"paramB":{"home":""}}
5.2 正確示例
a. 代碼
//-------- main.go ---------------
package main
import (
"github.com/gin-gonic/gin" // 引入Gin框架
"go-use/practise" // 代碼示例包
)
func main() {
engine := gin.Default()
practise.TestBindXml(engine)
_ = engine.Run()
}
//------ go-use/practise/param_bind.go -------
type BodyAParam struct {
Name string `json:"name"`
}
type BodyBParam struct {
Home string `json:"home"`
}
// 重複綁定request.Body(正確示例)
func TestBindBody2(engine *gin.Engine) {
engine.POST("/body2", func(context *gin.Context) {
paramA := BodyAParam{}
paramB := BodyBParam{}
// 讀取 c.Request.Body 並將結果存入上下文。
_ = context.ShouldBindBodyWith(¶mA,binding.JSON)
// 這時, 複用存儲在上下文中的 body。
_ = context.ShouldBindBodyWith(¶mB,binding.JSON)
context.JSON(200,gin.H{"paramA":paramA,"paramB":paramB})
})
}
b. 請求返回
# paramA和paramB都綁定成功
➜ curl -X POST http://127.0.0.1:8080/body2 -d '{"name":"李四","home":"上海"}'
{"paramA":{"name":"李四"},"paramB":{"home":"上海"}}
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/DKSsCtcORSpAKb18aHnAYw