社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
1.常用go字段校验库
https://github.com/go-playground/validator
https://github.com/asaskevich/govalidator
https://github.com/gookit/validate
https://github.com/smokezl/govalidators
2.常用校验库对比根据星星数,网上使用推荐,活跃程度以及维护情况来看,目前使用比较多的是validator和govalidator playground/validator包:基于标签对结构体和单个字段进行校验支持struct,slice,array和map等等数据类型;
支持struct的嵌套检查;
支持处理自定义字段类型,例如sql driver Valuer;
参数校验错误时输出是英文,支持转换成中文;
支持自定义验证标签和函数;
gin Web框架的默认验证器。
使用方式简单易懂,直接调用相应的函数即可;
包含丰富的检验函数;
支持struct的嵌套检查;
支持自定义tag与自定义校验函数;
govalidator除了支持校验,还支持较为丰富的字符串裁剪、处理、正则等功能,以及若干类型转换功能。
3. playground/validator库使用
A. 常用标记及说明
B. 用法示例
package mainimport ( "fmt" "github.com/go-playground/locales/zh" "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" zh_translations "github.com/go-playground/validator/v10/translations/zh")// User contains user informationtype User struct { FirstName string `validate:"required"` LastName string `validate:"required"` Age uint8 `validate:"gte=0,lte=130"` Email string `validate:"required,email"` FavouriteColor string `validate:"iscolor"` // alias for 'hexcolor|rgb|rgba|hsl|hsla' Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage...}// Address houses a users address informationtype Address struct { Street string `validate:"required"` City string `validate:"required"` Planet string `validate:"required"` Phone string `validate:"required"`}// use a single instance of Validate, it caches struct infovar validate *validator.Validatefunc main() { validate = validator.New() validateStruct() validateVariable()}func validateStruct() { address := &Address{ Street: "Eavesdown Docks", Planet: "Persphone", Phone: "none", } user := &User{ FirstName: "Badger", LastName: "Smith", Age: 135, Email: "Badger.Smith@gmail.com", FavouriteColor: "#000-", Addresses: []*Address{address}, } // returns nil or ValidationErrors ( []FieldError ) err := validate.Struct(user) if err != nil { // this check is only needed when your code could produce // an invalid value for validation such as interface with nil // value most including myself do not usually have code like this. if _, ok := err.(*validator.InvalidValidationError); ok { fmt.Println(err) return } for _, err := range err.(validator.ValidationErrors) { fmt.Println(err.Namespace()) fmt.Println(err.Field()) fmt.Println(err.StructNamespace()) fmt.Println(err.StructField()) fmt.Println(err.Tag()) fmt.Println(err.ActualTag()) fmt.Println(err.Kind()) fmt.Println(err.Type()) fmt.Println(err.Value()) fmt.Println(err.Param()) fmt.Println() } // from here you can create your own error messages in whatever language you wish return } // save user to database}func validateVariable() { //1.string myEmail := "joeybloggs.gmail.com" errs := validate.Var(myEmail, "required,email") processErr(errs) subString := "hello,china" errs = validate.Var(subString, "contains=china1") processErr(errs) syntaxCheck1 := "" syntaxCheck2 := "12312rdq2fwefdf" syntaxCheck3 := "45" errs = validate.Var(syntaxCheck1, "required,gt=0,lt=10") processErr(errs) errs = validate.Var(syntaxCheck2, "required,gt=0,lt=10") processErr(errs) errs = validate.Var(syntaxCheck3, "required,gt=0,lt=10") processErr(errs) //2.int numTest := 5 errs = validate.Var(numTest,"required,max=2") processErr(errs) //3.数组和切片 slice := make([]int, 2) slice[0] = 10 slice[1] = 10 errs = validate.Var(slice, "unique") processErr(errs) //4.map dict := make(map[string]int) dict["go"] = 100 dict["c"] = 50 errs = validate.Var(dict,"gt=1,dive,keys,required,endkeys,max=80") processErr(errs) //5.VarWithValue方法:两个变量的比较 errs = validate.VarWithValue(1,2, "eqfield") processErr(errs) //6.错误处理 errs = validate.Struct(numTest) processErr(errs) //7.自定义约束 palindromeStr := "djffj" validate.RegisterValidation("palindrom", checkPalindrome) errs = validate.Var(palindromeStr, "palindrom") processErr(errs) //8.转换成中文 //中文翻译器 zh_ch := zh.New() uni := ut.New(zh_ch) trans, _ := uni.GetTranslator("zh") //验证器注册翻译器 zh_translations.RegisterDefaultTranslations(validate,trans) errs = validate.Var("124.23.234.1234", "ip") if errs != nil { for _, validationErrs := range errs.(validator.ValidationErrors) { fmt.Println(validationErrs.Translate(trans)) } } charater := "中文" errs = validate.Var(charater, "alphaunicode") processErr(errs) cc := "中国" errs = validate.Var(cc,"alphanumunicode") processErr(errs) errs = validate.Var(cc,"alphanum") processErr(errs) return}func processErr(err error) { if err == nil { return } if invalid, ok := err.(*validator.InvalidValidationError); ok { fmt.Println("param error :", invalid) return } for _, validationErrs := range err.(validator.ValidationErrors) { fmt.Println(validationErrs) }}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(f1 validator.FieldLevel) bool { value := f1.Field().String() return value == reverseString(value)}
4. asaskevich/govalidator库的使用
A. 常用内置函数
B. govalidator专门提供了一个函数govalidator.ValidateStruct(),用于校验struct的元素
struct元素只支持部分常用的校验;
struct元素必须是导出型,也就是必须大写字母开头,govalidator才会去理会;
struct元素匹配较为智能,比如range(min|max)不仅支持string也支持int类型
C. 用法示例
package mainimport ( "fmt" "github.com/asaskevich/govalidator")type Foo struct { A string `valid:"ipv4"` B string `valid:"mac"` C int `valid:"range(0|100)"`}type bar struct { X string `valid:"ipv4"` Foo `valid:",required"`}func main() { govalidator.SetFieldsRequiredByDefault(true) // 判断字符串值是否为合法的IPv4地址 ip4 := "192.168.1.1" fmt.Println(govalidator.IsIPv4(ip4)) // true // 判断字符串值是否为合法的MAC mac := "aa:bb:cc:dd:ee:ffffff" fmt.Println(govalidator.IsMAC(mac)) // false // 判断数字是否在指定范围内 dig := 101 // string类型也可以用 fmt.Println(govalidator.InRange(dig, 0, 100)) // false //struct b := bar{ X: "192.168.1.1", } b.Foo.A = "192.168.1.1.12" b.Foo.B = "aa:bb:cc:dd:ee:ff" b.Foo.C = 100 result, err := govalidator.ValidateStruct(b) if err != nil { fmt.Println("error: " + err.Error()) } fmt.Println(result) //类型转换 a := "12131" fmt.Println(govalidator.ToFloat(a))}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!