1、介绍 在 Gin 框架中参数不但能通过指定 key
接收,也可以直接绑定到结构体中
1.1、绑定方法概览 Gin 提供了 Must bind
和 Should bind
两种类型的绑定方法,这两种类型对应的方法如下:
功能
Must bind方法
Should bind方法
Bind
ShouldBind
绑定JSON
BindJSON
ShouldBindJSON
绑定XML
BindXML
ShouldBindXML
绑定GET
BindQuery
ShouldBindQuery
绑定YAML
BindYAML
ShouldBindYAML
a.MustBindWith 和 ShouldBindWith
Bind*
类型的方法是对MustBindWith
封装;Should*
类型的方法是对ShouldBindWith
的封装;
Must bind
Methods - Bind
, BindJSON
, BindXML
, BindQuery
, BindYAML
Behavior - 这些方法属于 MustBindWith
的具体调用。 如果发生绑定错误,则请求终止,并触发 c.AbortWithError(400, err).SetType(ErrorTypeBind)
。响应状态码被设置为 400 并且 Content-Type
被设置为 text/plain; charset=utf-8
。 如果您在此之后尝试设置响应状态码,Gin会输出日志 [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422
。 如果您希望更好地控制绑定,考虑使用 ShouldBind
等效方法。
Should bind
Methods - ShouldBind
, ShouldBindJSON
, ShouldBindXML
, ShouldBindQuery
, ShouldBindYAML
Behavior - 这些方法属于 ShouldBindWith
的具体调用。 如果发生绑定错误,Gin 会返回错误并由开发者处理错误和请求。
1.2、绑定语法 定义被绑定的结构体
1 2 3 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、代码 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package mainimport ( "github.com/gin-gonic/gin" "go-use/practise" )func main () { engine := gin.Default() TestBindQuery(engine) _ = engine.Run() }type UriParam struct { Name string `form:"name" binding:"required"` Age int `form:"age"` Home string `form:"home"` }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、请求 1 2 3 4 5 6 7 8 9 10 [lepeng@centos ~] {"result" :{"Name" :"张三" ,"Age" :24,"Home" :"北京" }} [lepeng@centos ~] {"result" :{"Name" :"张三" ,"Age" :24,"Home" :"北京" }} [lepeng@centos ~] {"error" :"Key: 'UriParam.Name' Error:Field validation for 'Name' failed on the 'required' tag" }
3、绑定JSON 使用函数 BindJSON
和 ShouldBindJSON
来绑定提交的JSON
参数信息。
3.1、代码 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 26 27 28 29 30 31 32 33 34 35 36 37 package mainimport ( "github.com/gin-gonic/gin" "go-use/practise" )func main () { engine := gin.Default() practise.TestBindJson(engine) _ = engine.Run() }type Param struct { Name string `json:"name"` Age int `json:"age"` Likes []string `json:"likes"` }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、代码 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 26 27 28 29 30 31 32 33 34 35 36 package mainimport ( "github.com/gin-gonic/gin" "go-use/practise" )func main () { engine := gin.Default() practise.TestBindXml(engine) _ = engine.Run() }type Param struct { Name string `json:"name" xml:"name"` Age int `json:"age" xml:"age"` Likes []string `json:"likes" xml:"likes"` }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.代码
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 26 27 28 29 30 package mainimport ( "github.com/gin-gonic/gin" "go-use/practise" )func main () { engine := gin.Default() practise.TestBindXml(engine) _ = engine.Run() }type BodyAParam struct { Name string `json:"name"` }type BodyBParam struct { Home string `json:"home"` }func TestBindBody (engine *gin.Engine) { engine.POST("/body" , func (context *gin.Context) { paramA := BodyAParam{} paramB := BodyBParam{} _ = context.ShouldBindJSON(¶mA) _ = context.ShouldBindJSON(¶mB) context.JSON(200 ,gin.H{"paramA" :paramA,"paramB" :paramB}) }) }
b.请求返回
1 2 3 [lepeng@centos ~] {"paramA" :{"name" :"李四" },"paramB" :{"home" :"" }}
5.2、正确示例 a.代码
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 26 27 28 29 30 package mainimport ( "github.com/gin-gonic/gin" "go-use/practise" )func main () { engine := gin.Default() practise.TestBindXml(engine) _ = engine.Run() }type BodyAParam struct { Name string `json:"name"` }type BodyBParam struct { Home string `json:"home"` }func TestBindBody2 (engine *gin.Engine) { engine.POST("/body2" , func (context *gin.Context) { paramA := BodyAParam{} paramB := BodyBParam{} _ = context.ShouldBindBodyWith(¶mA,binding.JSON) _ = context.ShouldBindBodyWith(¶mB,binding.JSON) context.JSON(200 ,gin.H{"paramA" :paramA,"paramB" :paramB}) }) }
b.请求返回
1 2 3 [lepeng@centos ~] {"paramA" :{"name" :"李四" },"paramB" :{"home" :"上海" }}