gin-数据绑定+数据验证

将用户传来的参数和我们的绑定

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)

你可能感兴趣的:(gin-数据绑定+数据验证)