文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Gin 框架怎么使用自定义验证器?

2024-11-28 14:41

关注

其中结构体级别验证器,可以用于跨字段验证,也可以用于和字段级别验证器结合使用。

需要注意的是,结构体级别验证器的优先级小于字段级别验证器。

2.字段级别自定义验证器

定义字段级别验证器

示例代码:

var userValidator validator.Func = func(fl validator.FieldLevel) bool {
 val, ok := fl.Field().Interface().(string)
 if ok {
  illegalName := []string{"admin", "Admin", "guest", "Guest"}
  for _, v := range illegalName {
   if v == val {
    return false
   }
  }
 }
 return true
}

阅读上面这段代码,我们定义一个 validator.Func 类型的函数变量,参数入参的类型是 validator.FieldLevel,返回结果是一个 bool 类型的变量。

函数体中,使用类型断言,获取字段的值,然后进行逻辑验证。

注册自定义验证器

示例代码:

func main() {
 r := gin.Default()
 // 注册自定义验证器
 if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
  err := v.RegisterValidation("user_validator", userValidator)
  if err != nil {
   return
  }
 }
 r.GET("/login", Login)
 err := r.Run()
 if err != nil {
  return
 }
}

阅读上面这段代码,我们使用 RegisterValidation 方法,注册自定义验证器 userValidator,该方法接收的第一个参数是用于结构体字段的 tag 名称,第二个参数是自定义验证器的函数名称。

需要注意的是,如果我们注册的验证器标签名(用于结构体字段的 tag 名称)已存在,则会被当前验证器函数替换掉。

使用自定义验证器

示例代码:

func Login(c *gin.Context) {
 user := &User{}
 err := c.ShouldBind(user)
 if err != nil {
  c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  return
 }
 c.JSON(http.StatusOK, gin.H{
  "data": user,
 })
}

type User struct {
 Name     string `form:"name" binding:"required,user_validator"`
 Password string `form:"password"`
}

阅读上面这段代码,我们在请求参数结构体的字段中,添加我们注册自定义验证器时的标签名 user_validator,即可使用自定义验证器。

输出结果:

curl -s -X GET http://127.0.0.1:8080/login\?name\=admin\&password\=123456 | jq
{
  "error": "Key: 'User.Name' Error:Field validation for 'Name' failed on the 'user_validator' tag"
}

3.结构体级别自定义验证器

定义结构体级别验证器

示例代码:

func UserStructLevelValidation(sl validator.StructLevel) {
 user := sl.Current().Interface().(User)
 if len(user.TrueName) == 0 && len(user.NickName) == 0 {
  sl.ReportError(user.TrueName, "TrueName", "true_name", "true_name_or_nick_name", "")
  sl.ReportError(user.TrueName, "NickName", "nick_name", "true_name_or_nick_name", "")
 }
}

阅读上面这段代码,我们定义一个函数,该函数接收一个 validator.StructLevel 类型的参数,函数体中使用类型断言,获取结构体的值,然后进行逻辑验证。

注册自定义验证器

示例代码:

func main() {
 r := gin.Default()
 // 注册自定义验证器
 if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
  v.RegisterStructValidation(UserStructLevelValidation, User{})
 }
 r.POST("/register", Register)
 err := r.Run()
 if err != nil {
  return
 }
}

阅读上面这段代码,我们使用 RegisterStructValidation 方法,注册自定义验证器 UserStructLevelValidation,该方法接收两个参数,分别是 StructLevelFunc 函数类型的自定义验证器,和需要验证的结构体类型。

使用自定义验证器

示例代码:

func Register(c *gin.Context) {
 var user User
 err := c.ShouldBind(&user)
 if err != nil {
  c.JSON(http.StatusBadRequest, gin.H{
   "error": err.Error(),
  })
  return
 }
 c.JSON(http.StatusOK, gin.H{
  "data": user,
 })
}

type User struct {
 TrueName string `json:"true_name"`
 NickName string `json:"nick_name"`
 Password string `json:"password" binding:"required"`
}

阅读上面这段代码,我们不需要在结构体字段标签中有任何操作,即可使用自定义结构体级别的验证器。

以下是结构体级别验证器单独使用,和结合字段级别验证器(标签验证器)一起使用的输出结果。

输出结果:

curl -s -H "content-type: application/json" -X POST -d '{"true_name": "", "nick_name": "", "password": "123456"}' http://127.0.0.1:8080/register | jq
{
  "error": "Key: 'User.TrueName' Error:Field validation for 'TrueName' failed on the 'true_name_or_nick_name' tag\nKey: 'User.NickName' Error:Field validation for 'NickName' failed on the 'true_name_or_nick_name' tag"
}

curl -s -H "content-type: application/json" -X POST -d '{"true_name": "", "nick_name": "", "password": ""}' http://127.0.0.1:8080/register | jq  
{
  "error": "Key: 'User.Password' Error:Field validation for 'Password' failed on the 'required' tag\nKey: 'User.TrueName' Error:Field validation for 'TrueName' failed on the 'true_name_or_nick_name' tag\nKey: 'User.NickName' Error:Field validation for 'NickName' failed on the 'true_name_or_nick_name' tag"
}

4.总结

本文我们介绍 Gin 框架怎么使用自定义验证器,分别列举了字段级别和结构体级别自定义验证器的使用方式。

需要注意的是,它们并不是线程安全的,需要在任何验证之前,先注册自定义验证器。

来源:Golang语言开发栈内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯