自学内容网 自学内容网

【Golang】validator库的使用

package main

import (
"fmt"

"github.com/go-playground/validator"
)

// MyStruct .. validate:"is-awesome"是一个结构体标签,它告诉验证器使用名为is-awesome的验证规则来验证String字段。
type MyStruct struct {
String string `validate:"is-awesome"`
}

// use a single instance of Validate, it caches struct info
var validate *validator.Validate

func main() {

validate = validator.New()
//注册一个自定义验证函数ValidateMyVal,它将被用来验证标签为is-awesome的字段。
validate.RegisterValidation("is-awesome", ValidateMyVal)

s := MyStruct{String: "awesome"}

err := validate.Struct(s)
if err != nil {
fmt.Printf("Err(s):%+v\n", err)
}

s.String = "not awesome"
err = validate.Struct(s)
if err != nil {
fmt.Printf("Err(s):\n%+v\n", err)
}
}

// ValidateMyVal implements validator.Func
func ValidateMyVal(fl validator.FieldLevel) bool {
return fl.Field().String() == "awesome"
}

custom-validation  结果

Err(s):
Key: 'MyStruct.String' Error:Field validation for 'String' failed on the 'is-awesome' tag

示例代码2

custom

package main

import (
"database/sql"
"database/sql/driver"
"fmt"
"reflect"

"github.com/go-playground/validator/v10"
)

// DbBackedUser 用户结构体,由数据库支持
type DbBackedUser struct {
Name sql.NullString `validate:"required"` // 可以为NULL的字符串,验证规则为必填
Age  sql.NullInt64  `validate:"required"` // 可以为NULL的整数,验证规则为必填
}

// 使用单一实例的验证器,它缓存结构体信息
var validate *validator.Validate

func main() {
// 创建一个新的验证器实例
validate = validator.New()

// 注册所有sql.Null*类型,使用自定义的ValidateValuer函数
validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})

// 构建对象进行验证
// Name字段为空字符串但Valid为true,表示非NULL;Age字段为0且Valid为false,表示NULL
x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}}

// 对x进行结构体验证
err := validate.Struct(x)

// 如果验证失败,打印错误信息
if err != nil {
fmt.Printf("Err(s):\n%+v\n", err)
}
}

// ValidateValuer实现了validator.CustomTypeFunc接口
func ValidateValuer(field reflect.Value) interface{} {
// 如果field实现了driver.Valuer接口
if valuer, ok := field.Interface().(driver.Valuer); ok {
// 尝试获取valuer的值
val, err := valuer.Value()
if err == nil {
return val // 如果没有错误,返回值
}
// 如果有错误,可以根据需要处理
}
return nil // 如果没有实现Valuer接口或有错误,返回nil
}
// Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified.
//
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
func (v *Validate) Struct(s interface{}) error {
return v.StructCtx(context.Background(), s)
}

// StructCtx validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified
// and also allows passing of context.Context for contextual validation information.
//
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
func (v *Validate) StructCtx(ctx context.Context, s interface{}) (err error) {

val := reflect.ValueOf(s)
top := val

if val.Kind() == reflect.Ptr && !val.IsNil() {
val = val.Elem()
}

if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
return &InvalidValidationError{Type: reflect.TypeOf(s)}
}

// good to validate
vd := v.pool.Get().(*validate)
vd.top = top
vd.isPartial = false
// vd.hasExcludes = false // only need to reset in StructPartial and StructExcept

vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)

if len(vd.errs) > 0 {
err = vd.errs
vd.errs = nil
}

v.pool.Put(vd)

return
}
package main

import (
"fmt"

"github.com/go-playground/validator/v10"
)

// Test ...
type Test struct {
Array []string          `validate:"required,gt=0,dive,required"`
Map   map[string]string `validate:"required,gt=0,dive,keys,keymax,endkeys,required,max=1000"`
}

// use a single instance of Validate, it caches struct info
var validate *validator.Validate

func main() {

validate = validator.New()

// registering alias so we can see the differences between
// map key, value validation errors
validate.RegisterAlias("keymax", "max=10")//注册别名规则 max=10

var test Test

val(test)//空值报错required

test.Array = []string{""}//校验第一个字段非空require dive,required 
test.Map = map[string]string{"test > than 10": ""}//超过了max=10的最大长度 并且第二个值不为空
val(test)
test.Array = []string{"1"}
test.Map = map[string]string{"": "11"}//require针对value而不是key

val(test)
}

func val(test Test) {
fmt.Println("testing")
err := validate.Struct(test)
fmt.Println(err)
}

结合正则表达式

package main

import (
"database/sql"
"fmt"
"regexp"

"github.com/go-playground/validator/v10"
)

// DbBackedUser 用户结构体,由数据库支持
type DbBackedUser struct {
Name sql.NullString `validate:"required,namePattern"` // 可以为NULL的字符串,验证规则为必填和符合名称模式
Age  sql.NullInt64  `validate:"required,gt=0"`       // 可以为NULL的整数,验证规则为必填且大于0
}

// 使用单一实例的验证器,它缓存结构体信息
var validate *validator.Validate

func main() {
// 创建一个新的验证器实例
validate = validator.New()

// 注册自定义验证函数
validate.RegisterValidation("namePattern", NamePattern)
validate.RegisterValidation("gt", GreaterThanZero)

// 构建对象进行验证
x := DbBackedUser{Name: sql.NullString{String: "JohnDoe", Valid: true}, Age: sql.NullInt64{Int64: 18, Valid: true}}

// 对x进行结构体验证
err := validate.Struct(x)

// 如果验证失败,打印错误信息
if err != nil {
fmt.Printf("Err(s):\n%+v\n", err)
}else{
fmt.Println("success")
}


x = DbBackedUser{Name: sql.NullString{String: "JohnDoe_123", Valid: true}, Age: sql.NullInt64{Int64: 18, Valid: true}}

// 对x进行结构体验证
err = validate.Struct(x)

// 如果验证失败,打印错误信息
if err != nil {
fmt.Printf("Err(s):\n%+v\n", err)
}else{
fmt.Println("success")
}

}

// NamePattern 自定义验证函数,检查姓名是否只包含字母
func NamePattern(fl validator.FieldLevel) bool {
nullString := fl.Field().Interface().(sql.NullString)
if !nullString.Valid {
return false
}
reg := regexp.MustCompile(`^[a-zA-Z]+$`)
return reg.MatchString(nullString.String)
}

// GreaterThanZero 自定义验证函数,检查数值是否大于0
func GreaterThanZero(fl validator.FieldLevel) bool {
nullInt64 := fl.Field().Interface().(sql.NullInt64)
if !nullInt64.Valid {
return false
}
return nullInt64.Int64 > 0
}

参考validator/_examples at master · go-playground/validator · GitHub


原文地址:https://blog.csdn.net/lcadna/article/details/143578957

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!