赞
踩
Validator 是一个 Golang 的第三方库,用于对数据进行校验,常用于 API 的开发中,对客户端发出的请求数据进行严格校验,防止恶意请求。
安装:
go get gopkg.in/go-playground/validator.v10
使用:
import "github.com/go-playground/validator/v10"
NOTE:validator 当前最新的版本是 v10,各个版本之间有一些差异,在使用的时候要注意区分。
validator 应用了 Golang 的 Struct Tag 和 Reflect 机制,基本思想是:在 Struct Tag 中为不同的字段定义各自类型的约束,然后通过 Reflect 获取这些约束的类型信息并在校验器中进行数据校验。如下例:
package main import ( "fmt" "gopkg.in/go-playground/validator.v10" ) type User struct { Name string `validate:"min=6,max=10"` Age int `validate:"min=1,max=100"` } func main() { validate := validator.New() u1 := User{Name: "fanguiju", Age: 18} err := validate.Struct(u1) fmt.Println(err) u2 := User{Name: "fgj", Age: 101} err = validate.Struct(u2) fmt.Println(err) }
上述例子中,我们定义了结构体 User,有 Name 和 Age 成员。通过 validator 的 min 和 max 约束,分别约束了 Name 的字符串长度 [6, 10],Age 的数字范围为 [1,100]。
使用 validator 的第一步需要 New(构造)一个 “校验器”,然后调用其 Struct 方法对结构体实例进行校验。如果满足约束则返回 nil,否则返回相应的错误信息。
validate:"structonly"
。validate:"nostructlevel"
。[][]string
:validate:"gt=0,dive,len=1,dive,required"
。validate:"gt=0,dive,keys,eq=1\|eq=2,endkeys,required"
。Tags:
下面列举常用的字符串约束:
唯一性(unique)约束,对不同类型的处理如下:
validator 允许定义跨字段的约束,即:约束某个字段与其他字段之间的关系。这种约束实际上分为两种:
约束语法很简单,如果是约束同一个结构中的字段,则在基础的 Tags 后面添加一个 field 后缀,例如:eqfield 定义字段间的相等(eq)约束。如果是更深层次的字段,在 field 之前还需要加上 cs(Cross-Struct),eq 就变为了 eqcsfield。
示例:
type RegisterForm struct {
Name string `validate:"min=2"`
Age int `validate:"min=18"`
Password string `validate:"min=10"`
Password2 string `validate:"eqfield=Password"`
}
即:他们组成就是 “比较符号 + 是否跨 Struct(cross struct) + field”:
另外还有几个挺有用的 Tag:
除了使用 validator 提供的内建约束外,还可以定义自己的约束。首先定义一个类型为 func (validator.FieldLevel) bool 的函数检查约束是否满足,可以通过 FieldLevel 取出要检查的字段的信息。然后,调用校验器的 RegisterValidation() 方法将该约束注册到指定的名字上。最后我们就可以在结构体中使用该约束了。
示例:
type RegisterForm struct { Name string `validate:"palindrome"` Age int `validate:"min=18"` } func reverseString(s string) string { runes := []rune(s) for from, to := 0, len(runes)-1; from < to; from, to = from+1, to-1 { runes[from], runes[to] = runes[to], runes[from] } return string(runes) } func CheckPalindrome(fl validator.FieldLevel) bool { value := fl.Field().String() return value == reverseString(value) } func main() { validate := validator.New() validate.RegisterValidation("palindrome", CheckPalindrome) f1 := RegisterForm{ Name: "djd", Age: 18, } err := validate.Struct(f1) if err != nil { fmt.Println(err) } f2 := RegisterForm{ Name: "dj", Age: 18, } err = validate.Struct(f2) if err != nil { fmt.Println(err) } }
validator 返回的错误有两种,一种是参数错误,一种是校验错误,它们都实现了 error 接口。
所以 validator 校验返回的结果只有 3 种情况:
我们可以在程序中判断 err != nil 时,可以依次将 err 转换为 InvalidValidationError 和 ValidationErrors 以获取更详细的信息:
func processErr(err error) { if err == nil { return } invalid, ok := err.(*validator.InvalidValidationError) if ok { fmt.Println("param error:", invalid) return } validationErrs := err.(validator.ValidationErrors) for _, validationErr := range validationErrs { fmt.Println(validationErr) } } func main() { validate := validator.New() err := validate.Struct(1) processErr(err) err = validate.VarWithValue(1, 2, "eqfield") processErr(err) }
需要安装两个包:
go get github.com/go-playground/universal-translator
go get github.com/go-playground/locales
示例:
package main import ( "fmt" "github.com/go-playground/locales/zh" ut "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" zh_translations "github.com/go-playground/validator/v10/translations/zh" ) type Users struct { Name string `form:"name" json:"name" validate:"required"` Age uint8 `form:"age" json:"age" validate:"required,gt=18"` Passwd string `form:"passwd" json:"passwd" validate:"required,max=20,min=6"` Code string `form:"code" json:"code" validate:"required,len=6"` } func main() { users := &Users{ Name: "admin", Age: 12, Passwd: "123", Code: "123456", } // 中文翻译器 uni := ut.New(zh.New()) trans, _ := uni.GetTranslator("zh") // 校验器 validate := validator.New() // 注册翻译器到校验器 err := zh_translations.RegisterDefaultTranslations(validate, trans) if err!=nil { fmt.Println(err) } err = validate.Struct(users) if err != nil { for _, err := range err.(validator.ValidationErrors) { fmt.Println(err.Translate(trans)) return } } return }
https://blog.csdn.net/qq_26273559/article/details/107164846
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。