golang validator 包的使用指北

简介: golang validator 包的使用指北

看到 validator 咱们第一反应会想起啥?见名知意我就可以知道他是一个验证器,如果用过 gin web 框架的同学,自然是用过 gin 里面的 validator,只不过 gin 中使用的关键字是 binding 去做标识

开门见山

Validator 实际上是一个验证工具,属于 golang 的第三方包,这个包中使用了各种反射技巧来提供了各种校验和约束数据的方式方法,非常实用,常用的有这些:

  • 基本的字段长度,大小,范围的约束
  • len:约束参数长度
  • eq:数值等于参数值
  • max:数值小于等于参数值
  • min:数值大于等于参数值
  • ne:不等于参数值
  • gt:大于参数值,gte:大于等于参数值
  • lt:小于参数值, lte:小于等于参数值
  • oneof:只能是枚举值中的一个,这些值必须是数值或字符串,以空格分隔,如果字符串中有空格,则使用单引号包围。例如:oneof=changsha beijing haerbing
  • 是否必选,是否跳过,是否忽略
  • -:跳过该字段
  • | :使用多个约束,只需要满足其中一个,例如:xxx| xxx
  • required:必选约束,不能为默认值
  • omitempty:如果字段未设置,则忽略它
  • 各种格式约束如
  • email
  • url
  • ip、ipv4、ipv6
  • uuid
  • datetime
  • json
  • file , 参数必须是一个合法的文件路径

常用的大概有上述这些,我们也不需要去背,只需要知道如何去使用,以及咱们需要处理数据校验的时候,能够想到 validator 库就行了,实在记不起来看官方文档或者看本篇文章的例子就可以了,这个是官网:

validator package - github.com/go-playground/validator/v10 - Go Packages

使用

使用 validator 工具, 自然是为了提高我们的开发效率以及让我们写出来的内容更加优雅和健壮

如果我们自己每一个字段都显示的去校验是否符合我们预期,那么代码大概率会很臃肿,来一个简单的 demo,举个栗子

package main
import (
   "fmt"
   "github.com/go-playground/validator/v10"
)
type Data struct {
   City       string `validate:"min=8,max=15"`
   Name       string `validate:"min=6,max=10"`
   Addr       string `validate:"url"`
   Age        int    `validate:"gte=18,lte=100"`
   Tall       int    `validate:"required"`
   IpAddr     string `validate:"ipv4"`
   Email      string `validate:"email"`
   Content    string `validate:"json"`
   CreateTime string `validate:"datetime=2006-01-02"`
   NewPwd     string `validate:"min=8"`
   RePwd      string `validate:"eqfield=NewPwd"`
}
func main() {
   // 示例 , 基本使用介绍
   validate := validator.New()
   demo1 := Data{
      City:       "changsha11111111111111",
      Name:       "xiaozhu",
      Addr:       "xxxxxxxxx",
      Age:        25,
      Tall:       185,
      IpAddr:     "xxxxxxxxxxx",
      Email:      "helloworld@qq.com",
      Content:    "{"name":"xiaozhu"}",
      CreateTime: "xxxxx2006-03-02",
      NewPwd:     "12345",
      RePwd:      "123456789xxxxx",
   }
   err := validate.Struct(demo1)
   if err == nil {
      fmt.Println("params check success")
      return
   }
   invalid, ok := err.(*validator.InvalidValidationError)
   if ok {
      fmt.Println("param invalid : ", invalid)
      return
   }
   valiErrs := err.(validator.ValidationErrors)
   for _, valiErr := range valiErrs {
      fmt.Println(valiErr)
   }
}

此处我们可以看到我们在 Data 数据结构中,对其成员进行了不同的约束,相信通过 xdm 看到 Data 结构中的 validate 标识后面的约束,就知道响应字段的约束是啥意思了

例如

Age int `validate:"gte=18,lte=100"`

约束 Age 这个字段,需要满足 大于等于 18 ,小于等于 100 的范围

RePwd string `validate:"eqfield=NewPwd"`

RePwd 字段,需要和 NewPwd 字段相等 ,这个是用 eqfield 做标识的

关于 xxfield 的跨字段约束的相关标识可以查看官网的此处

这里是 valiator 能支持的所有类型,从字段内容,网络方面,字符串,数据结构,比较的字符,其他的标识

另外关于邮箱约束的:

Email string `validate:"email"`

Email 字段,必须是 email 格式的,才能够检验通过

如上,每一个字段,如果需要校验的,校验失败,我们也可以全部打印出来

目前在 validator 中,处理错误信息,分为 2 种错误的情况:

  • InvalidValidationError

咱们将我们的 err 转换成 InvalidValidationError ,表示输入参数错误

  • ValidationErrors:字段违反约束,错误信息如下

咱们将我们的 err 转换成 ValidationErrors,这是一个切片,所以咱们可以遍历输出,这个是表示不符合约束字符的有错误原因

validator.ValidationErrors 是一个 FieldError 类型的切片

type ValidationErrors []FieldError

FieldError 中包含了关于 error 的全部信息,我们可以调用 FieldError 里面的成员方法进行输出即可

type FieldError interface {
   Tag() string
   ActualTag() string
   Namespace() string
   StructNamespace() string
   Field() string
   StructField() string
   Value() interface{}
   Param() string
   Kind() reflect.Kind
   Type() reflect.Type
   Translate(ut ut.Translator) string
   Error() string
}

关于其他标识的使用就不过多赘述了,使用方式都大同小异,咱们可以参考上述的 demo 即可

自定义约束

当然,如果认为官方提供的支持的标识还不能满足我们的要求,那么我们也是可以自定义咱们的标识的,例如,咱们要定义的标识是 happyhead含义就是,咱们定义的字符串,必须是以 happy 开头的,否则就校验不通过

此时咱们就需要使用到 validator 包中的 RegisterValidation 方法,再按照这个方法,提供一个校验实际参数的回调函数即可:

我们就可以这样来写

查看实际效果如下:

demo1 validate failed :  Key: 'RegisterFormat.Name' Error:Field validation for 'Name' failed on the 'happyhead' tag
demo2 validate success ...

至此,咱们将 validator 包中的特殊约束,格式约束,错误处理,范围约束,字符串约束,以及自定义约束都简单过了一下,这些东西不需要朗读和背诵,只需要咱们知道有他,需要的时候,能够找到,能够迅速使用起来即可

当然,如果想研究他的实现原理的,可以好好看看 validator 源码包以及官方文档,还是非常有意思的

感谢阅读,欢迎交流,点个赞,关注一波 再走吧

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI

相关文章
|
3月前
|
Go
Golang的math包常用方法
这篇文章介绍了Golang的math包中的常量和常用方法,并通过示例代码展示了如何使用这些常量和方法。
179 87
Golang的math包常用方法
|
3月前
|
存储 Go
Golang语言基于go module方式管理包(package)
这篇文章详细介绍了Golang语言中基于go module方式管理包(package)的方法,包括Go Modules的发展历史、go module的介绍、常用命令和操作步骤,并通过代码示例展示了如何初始化项目、引入第三方包、组织代码结构以及运行测试。
54 3
|
3月前
|
Go
Golang语言基于GOPATH方式管理包(package)
这篇文章详细介绍了Golang语言中基于GOPATH方式管理包(package)的方法,包括包的概述、定义、引入格式、别名使用、匿名引入,以及如何快速入门自定义包,并通过具体代码案例展示了包的环境准备、代码编写、细节说明和程序运行。
41 3
|
3月前
|
Go
Golang语言之包依赖管理
这篇文章详细介绍了Go语言的包依赖管理工具,包括godep和go module的使用,以及如何在项目中使用go module进行依赖管理,还探讨了如何导入本地包和第三方库下载的软件包存放位置。
41 3
|
4月前
|
机器学习/深度学习 存储 人工智能
Golang bytes 包学习
Golang bytes 包学习
26 3
|
4月前
|
Go 开发者
|
4月前
|
存储 测试技术 Go
Golang 包:构建模块化代码的基石
【8月更文挑战第31天】
48 0
|
6月前
|
SQL NoSQL Go
技术经验分享:Golang标准库:errors包应用
技术经验分享:Golang标准库:errors包应用
43 0
|
6月前
|
移动开发 Go
golang bufio包怎么用?
`bufio` 是 Go 语言中用于提高 I/O 性能的包,它通过使用缓冲区减少对低效磁盘 I/O 操作的调用。简而言之,`bufio` 提供带缓冲的读写功能,减少读取或写入文件时的系统调用次数,从而提升程序性能。
|
7月前
|
监控 Go 开发者
Golang深入浅出之-Goroutine泄漏检测与避免:pprof与debug包
【5月更文挑战第2天】本文介绍了Go语言并发编程中可能遇到的Goroutine泄漏问题,以及如何使用`pprof`和`debug`包来检测和防止这种泄漏。常见的问题包括忘记关闭channel和无限制创建goroutine。检测方法包括启动pprof服务器以监控Goroutine数量,使用`debug.Stack()`检查堆栈,以及确保每个Goroutine有明确的结束条件。通过这些手段,开发者可以有效管理Goroutine,维持程序性能。
257 7