将用户传来的参数和我们的绑定
type Login struct {
User string `form:"name" json:"name" binding:"required"`
//这里有做简单验证,表示参数是必须的
Age string `form:"age" json:"age" binding:"required"`
}
绑定url查询参数到结构体,实质就是上一步获取到参数,然后新建一个结构体,这样在golang里面就可以用新的结构体来做操作了
r.Any("/test", func(c *gin.Context) {
var persion Login
if c.ShouldBindQuery(&persion) == nil {
fmt.Println(persion.User)
}
c.String(200, "ok")
})
绑定url查询参数和POST参数
r.POST("/t", func(c *gin.Context) {
var persion Login
if c.ShouldBind(&persion) == nil {
fmt.Println(persion.User)
fmt.Println(persion.Age)
} else {
fmt.Println("传入参数失败")
}
c.String(200, "haha")
})
1 .首先会检查url查询字符串和post的数据,而且会根据content-type的类型,优先匹配JSON或者xml,最后才是form类型的数据
2 .
数据验证
1 .简单的验证就是拿到生成的数据进行一下判断
2 .自定义验证:本质就是通过定义一些检查方法,来判断数据是否符合要求,这里要仔细掌握
Must bind
1 .Bind,BindJSON,BindXML,BindQuery,BindYAML
2 .这些方法底层使用MustBindWith,如果存在绑定错误,请求将被以下指令终止。c.AbortWithError(400,err)
3 .如果想要更好的控制行为,应该使用ShouldBind相关的方法
Should bind
1 .ShouldBind,ShouldBindJSON,ShoudBindXML,ShouldBindQuery,ShouldBIndYAML
2 .这些方法底层使用ShoudlBInd相关方法
r.POST("/test",func(c *gin.Context){
var json Login
if err:=c.ShouldBindJSON(&json);err!=nil{
c.JSON(200,gin.H{
"err":err.Error(),
})
}else{
fmt.Println(json.User)
c.String(200,"asdfa")
}
})
{
"err": "invalid character '-' in numeric literal"
},会报错
只绑定GET参数:ShouldBindQuery
r.GET("/test",func(c *gin.Context){
var json Login
if err:=c.ShouldBindQuery(&json);err!=nil{
c.JSON(200,gin.H{
"err":err.Error(),
})
}else{
fmt.Println(json)
c.String(200,"asdfa")
}
})
绑定GET或者POST参数
r.Any("/test",func(c *gin.Context){
var json Login
if err:=c.ShouldBind(&json);err!=nil{
c.JSON(200,gin.H{
"err":err.Error(),
})
}else{
fmt.Println(json)
c.String(200,"asdfa")
}
})
1 .如果是GET,那么不会收到POST中的请求
2 .如果是POST,会首先判断content-type的类型,然后使用对应的类型进行转换http://localhost:8080/test?user=asdf&password=url,这样的post url也只会解析post提交的数据,不会解析url的参数的
3 .
绑定url
r.GET("/test/:name/:id",func(c *gin.Context){
var json Login
if err:=c.ShouldBindUri(&json);err!=nil{
// 如果url绑定和get参数一起混合怎么办?
c.JSON(400,gin.H{
"msg":err,
})
return
}
c.JSON(200,gin.H{
"name":json.Name,
"id":json.ID,
})
})
//返回参数
{"msg":{"Login.ID":{"FieldNamespace":"Login.ID","NameNamespace":"ID","Field":"ID","Name":"ID","Tag":"uuid","ActualTag":"uuid","Kind":24,"Type":{},"Param":"","Value":"123123123"}}}
绑定HTML复选框
1 .
绑定POST参数
1 .
将请求体绑定到不同的结构体中
1 .if else可以在处理errA之后进行,正常情况不是会只绑定一个吗?
type formA struct {
Foo string `json:"foo" xml:"foo" binding:"required"`
}
type formB struct {
Bar string `json:"bar" xml:"bar" binding:"required"`
}
func SomeHandler(c *gin.Context) {
objA := formA{}
objB := formB{}
// This c.ShouldBind consumes c.Request.Body and it cannot be reused.
if errA := c.ShouldBind(&objA); errA == nil {
c.String(http.StatusOK, `the body should be formA`)
// Always an error is occurred by this because c.Request.Body is EOF now.
} else if errB := c.ShouldBind(&objB); errB == nil {
c.String(http.StatusOK, `the body should be formB`)
} else {
...
}
}
2 .想要多次绑定
func SomeHandler(c *gin.Context) {
objA := formA{}
objB := formB{}
// 读取 c.Request.Body 并将结果存入上下文。
if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
c.String(http.StatusOK, `the body should be formA`)
// 这时, 复用存储在上下文中的 body。
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
c.String(http.StatusOK, `the body should be formB JSON`)
// 可以接受其他格式
} else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
c.String(http.StatusOK, `the body should be formB XML`)
} else {
...
}
}
1 .c.ShouldBindBodyWith 会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法。
2 .只有某些格式需要此功能,如 JSON, XML, MsgPack, ProtoBuf。 对于其他格式, 如 Query, Form, FormPost, FormMultipart 可以多次调用 c.ShouldBind() 而不会造成任任何性能损失 (
绑定映射查询字符串或表单参数
1 .其实觉得这个有点没必要,也没遇到几个网站是这样搞得http://localhost:8080/test?ids[a]=1234&ids[b]=hello
ids:=c.QueryMap("ids")
// 会返回一个map
fmt.Println(ids)