01
介绍
Validator 是基于 tag(标记)实现结构体和单个字段的值验证库,它包含以下功能:
- 使用验证 tag(标记)或自定义验证器进行跨字段和跨结构体验证。
- 关于 slice、数组和 map,允许验证多维字段的任何或所有级别。
- 能够深入 map 键和值进行验证。
- 通过在验证之前确定接口的基础类型来处理类型接口。
- 处理自定义字段类型(如 sql 驱动程序 Valuer)。
- 别名验证标记,它允许将多个验证映射到单个标记,以便更轻松地定义结构体上的验证。
- 提取自定义的字段名称,例如,可以指定在验证时提取 JSON 名称,并在生成的 FieldError 中使用该名称。
- 可自定义 i18n 错误消息。
- Web 框架 gin 的默认验证器。
安装:
使用 go get:
go get github.com/go-playground/validator/v10
然后将 Validator 包导入到代码中:
import "github.com/go-playground/validator/v10"
02
变量验证
Var 方法使用 tag(标记)验证方式验证单个变量。
func (*validator.Validate).Var(field interface{}, tag string) error
它接收一个 interface{} 空接口类型的 field 和一个 string 类型的 tag,返回传递的非法值得无效验证错误,否则将 nil 或 ValidationErrors 作为错误。如果错误不是 nil,则需要断言错误去访问错误数组,例如:
validationErrors := err.(validator.ValidationErrors)
如果是验证数组、slice 和 map,可能会包含多个错误。
示例代码:
func main() { validate := validator.New() // 验证变量 email := "admin#admin.com" email := "" err := validate.Var(email, "required,email") if err != nil { validationErrors := err.(validator.ValidationErrors) fmt.Println(validationErrors) // output: Key: '' Error:Field validation for '' failed on the 'email' tag // output: Key: '' Error:Field validation for '' failed on the 'required' tag return } }
03
结构体验证
结构体验证结构体公开的字段,并自动验证嵌套结构体,除非另有说明。
func (*validator.Validate).Struct(s interface{}) error
它接收一个 interface{} 空接口类型的 s,返回传递的非法值得无效验证错误,否则将 nil 或 ValidationErrors 作为错误。如果错误不是 nil,则需要断言错误去访问错误数组,例如:
validationErrors := err.(validator.ValidationErrors)
实际上,Struct 方法是调用的 StructCtx 方法,因为本文不是源码讲解,所以此处不展开赘述,如有兴趣,可以查看源码。
示例代码:
func main() { validate = validator.New() type User struct { ID int64 `json:"id" validate:"gt=0"` Name string `json:"name" validate:"required"` Gender string `json:"gender" validate:"required,oneof=man woman"` Age uint8 `json:"age" validate:"required,gte=0,lte=130"` Email string `json:"email" validate:"required,email"` } user := &User{ ID: 1, Name: "frank", Gender: "boy", Age: 180, Email: "gopher@88.com", } err = validate.Struct(user) if err != nil { validationErrors := err.(validator.ValidationErrors) // output: Key: 'User.Age' Error:Field validation for 'Age' failed on the 'lte' tag // fmt.Println(validationErrors) fmt.Println(validationErrors.Translate(trans)) return } }
细心的读者可能已经发现,错误输出信息并不友好,错误输出信息中的字段不仅没有使用备用名(首字母小写的字段名),也没有翻译为中文。通过改动代码,使错误输出信息变得友好。
注册一个函数,获取结构体字段的备用名称:
validate.RegisterTagNameFunc(func(fld reflect.StructField) string { name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] if name == "-" { return "j" } return name })
错误信息翻译为中文:
zh := zh.New() uni = ut.New(zh) trans, _ := uni.GetTranslator("zh") _ = zh_translations.RegisterDefaultTranslations(validate, trans)
04
标签
通过以上章节的内容,读者应该已经了解到 Validator 是一个基于 tag(标签),实现结构体和单个字段的值验证库。
本章节列举一些比较常用的标签:
标签 | 描述 |
eq |
等于 |
gt |
大于 |
gte |
大于等于 |
lt |
小于 |
lte |
小于等于 |
ne |
不等于 |
max | 最大值 |
min | 最小值 |
oneof |
其中一个 |
required |
必需的 |
unique | 唯一的 |
isDefault |
默认值 |
len | 长度 |
邮箱格式 |
05
总结
本文简单介绍了在 Go 语言中比较流行的值验证库 Validator,通过简单示例介绍了 validator 的一般用法,并列举了一些常用的 tag。Validator 的功能非常强大,限于篇幅,无法一一介绍。如果读者感兴趣,想更加深入了解 validator,请参考 validator 的 Github 仓库中的相关介绍,文末给出了链接地址。