当前位置: 首页 > news >正文

【Golang】validator库的使用

package mainimport ("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.Validatefunc 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 mainimport ("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.Validatefunc 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,表示NULLx := 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 := valif 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 validatevd := v.pool.Get().(*validate)vd.top = topvd.isPartial = false// vd.hasExcludes = false // only need to reset in StructPartial and StructExceptvd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)if len(vd.errs) > 0 {err = vd.errsvd.errs = nil}v.pool.Put(vd)return
}
package mainimport ("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.Validatefunc main() {validate = validator.New()// registering alias so we can see the differences between// map key, value validation errorsvalidate.RegisterAlias("keymax", "max=10")//注册别名规则 max=10var test Testval(test)//空值报错requiredtest.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而不是keyval(test)
}func val(test Test) {fmt.Println("testing")err := validate.Struct(test)fmt.Println(err)
}

结合正则表达式

package mainimport ("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.Validatefunc 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


http://www.mrgr.cn/news/67379.html

相关文章:

  • 论文阅读--基于MLS点云语义分割和螺栓孔定位的盾构隧道错位检测方法
  • 基于SpringBoot的“会员制医疗预约服务管理信息系统”的设计与实现(源码+数据库+文档+PPT)
  • 【CSS in Depth 2 精译_056】8.4 CSS 的新特性——原生嵌套(Nesting)+ 8.5 本章小结
  • 在docker中搭建redis哨兵环境
  • LeetCode46. 全排列(2024秋季每日一题 57)
  • 数据安全-接口数据混合加密笔记
  • Unity网络通信(part5.编写服务端与客户端)
  • Redis集群模式之Redis Sentinel vs Redis Cluster
  • 基于特征工程的勒索软件检测方法研究项目申请
  • AI - 使用LangChain请求LLM结构化生成内容
  • 科研绘图系列:python语言连线图(linechart)
  • 小鹏AI机器人XPENG Iron亮相 采用端到端AI鹰眼视觉系统
  • 【系统集成项目管理工程师教程】第12章 执行过程组
  • Java | Leetcode Java题解之第542题01矩阵
  • 构建 Tencent SGX 机密计算环境
  • 十二:java web(4)-- Spring核心基础
  • GPU释放威力:在Gymnasium环境中使用稳定基线3在AMD GPU上训练强化学习代理
  • 科比投篮预测的数据处理与分析
  • 网络初始:TCP/IP 五层协议模型 网络通信基本流程
  • 解释Python的排序方法sort和sorted的区别。
  • 详解Rust标准库:BTreeSet
  • 数字信号处理Python示例(7)生成复数指数函数
  • Python | Leetcode Python题解之第543题二叉树的直径
  • 提高区块链网络TPS七步曲
  • 【知识科普】使用 OpenSSL为特定域名生成自签名证书
  • Python 详细实现无损压缩之 DEFLATE 算法