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" :"上海" }}