zoukankan      html  css  js  c++  java
  • golang之数据验证validator

    golang之数据验证validator

    前言

    普通验证对struct的数据方法比较繁琐,这里介绍一个使用比较多的包:validator

    原理

    将验证规则写在struct对字段tag里,在通过反射获取struct的tag,实现数据验证

    安装

    go get github.com/go-playground/validator
    

    标记之间特殊符号说明

    • 逗号(,):把多个验证标记隔开。注意:逗号前面和后面都不能有空格,否则panic
    • 横线(-):跳过该字段不验证
    • 竖线(|):使用多个验证标记,但是只需要满足其中一个即可
    • required:必填
    • omitempty:如果字段未设置,则忽略它

    特殊字符串验证

    • email:验证字符串是email格式。默认为必填
    • url:验证字符串是URL格式。默认为必填
    • uri:字段值是否包含有效的uri,validate:"uri"
    • ip:字段值是否包含有效的IP地址,validate:"ip"
    • ipv4:字段值是否包含有效的ipv4地址,validate:"ipv4"
    • ipv6:字段值是否包含有效的ipv6地址,validate:"ipv6"

    不跨字段范围验证规则

    • max&min:max字符串最大长度,min字符串最小长度
    • len:len字符串长度必须为n,或者是数组、切片、map的len的值
    • eq:数字等于n
    • ne:数字不等n
    • gt:数字大于n
    • gte:数字大于等于n
    • lt:小于n
    • lte:小于等于n

    示例(特殊字符串和不跨字段范围验证规则)

    package main
    
    import (
    	"log"
    
    	"github.com/go-playground/validator"
    )
    
    type Users struct {
    	Phone  string `validate:"required"`              // 必填
    	Email  string `validate:"email"`                 // 验证字符串是email格式。默认为必填
    	Url    string `validate:"url"`                   // 验证字符串是URL格式。默认为必填
    	Passwd string `validate:"required,max=20,min=6"` // max字符串最大长度,min字符串最小长度
    	Code   string `validate:"required,len=6"`        // len字符串长度必须为n,或者是数组、切片、map的len的值
    	Eq     int    `validate:"eq=4"`                  // eq数字等于n
    	Ne     int    `validate:"ne=4"`                  // ne数字不等n
    	Gt     int    `validate:"gt=4"`                  // gt数字大于n
    	Gte    int    `validate:"gte=4"`                 // gte数字大于等于n
    	Lt     int    `validate:"lt=4"`                  // lt小于n
    	Lte    int    `validate:"lte=4"`                 // lte小于等于
    }
    
    func init() {
    	log.SetFlags(log.Ldate | log.Lshortfile | log.Ltime)
    }
    
    func main() {
    	users := Users{
    		Phone:  "1326654487",
    		Email:  "1843121593@qq.com",
    		Url:    "https://blog.csdn.net/guyan0319/article/details/105918559",
    		Passwd: "123456",
    		Code:   "123456",
    		Eq:     4,
    		Ne:     3,
    		Gt:     5,
    		Gte:    4,
    		Lt:     3,
    		Lte:    4,
    	}
    	log.Printf("users:%+v
    ", users)
    	validate := validator.New()
    	validatErr := validate.Struct(&users)
    	errs := make([]validator.FieldError, 0)
    	if validatErr != nil {
    		for _, err := range validatErr.(validator.ValidationErrors) {
    			errs = append(errs, err)
    		}
    	}
    	if len(errs) != 0 {
    		for i := 0; i < len(errs); i++ {
    			log.Println(errs[i])
    		}
    	}
    }
    

    字符串验证

    • contains:包含参数子串。validate:"contains=ysm" (字段的字符串值包含ysm)
    • excludes:不包含参数子串,validate:"excludes=tom" (字段的字符串值不包含tom)
    • startswith:以参数子串为前缀,validate:"startswith=golang"
    • endswith:以参数子串为后缀,validate:"startswith=world"

    示例

    package main
    
    import (
    	"log"
    
    	"github.com/go-playground/validator"
    )
    
    type Teacher struct {
    	Contains   string `validate:"contains=ysm"`     // 包含参数子串。validate:"contains=ysm" (字段的字符串值包含ysm)
    	Excludes   string `validate:"excludes=tom"`     // excludes:不包含参数子串,validate:"excludes=tom" (字段的字符串值不包含tom)
    	Startswith string `validate:"startswith=start"` // startswith:以参数子串为前缀,validate:"startswith=golang"
    	Endswith   string `validate:"endswith=end"`     // endswith:以参数子串为后缀,validate:"startswith=world"
    }
    
    func teacher() {
    	teacher := Teacher{
    		Contains:   "ysmisgood",
    		Excludes:   "isgood",
    		Startswith: "startgogo",
    		Endswith:   "gogoend",
    	}
    	log.Printf("teacher:%+v
    ", teacher)
    	validate := validator.New()
    	validatErr := validate.Struct(&teacher)
    	errs := make([]validator.FieldError, 0)
    	if validatErr != nil {
    		for _, err := range validatErr.(validator.ValidationErrors) {
    			errs = append(errs, err)
    		}
    	}
    	if len(errs) != 0 {
    		for i := 0; i < len(errs); i++ {
    			log.Println(errs[i])
    		}
    	}
    }
    
    func main(){
    	teacher()
    }
    

    跨字段验证

    • eqfield=Field: 必须等于 Field 的值
    • nefield=Field: 必须不等于 Field 的值
    • gtfield=Field: 必须大于 Field 的值
    • gtefield=Field: 必须大于等于 Field 的值
    • ltfield=Field: 必须小于 Field 的值
    • ltefield=Field: 必须小于等于 Field 的值
    • eqcsfield:跨不同结构体字段验证,比如说 Struct1 Filed1,与结构体Struct2 Field2相等 (字段之间为包含关系,并且只能是在Struct1 Filed1 = Struct2 Field2,但是不能Struct2 Field2 = Struct1 Filed1)
    • necsfield=Other.Field: 必须不等于 struct Other 中 Field 的值
    • gtcsfield=Other.Field: 必须大于 struct Other 中 Field 的值
    • gtecsfield=Other.Field: 必须大于等于 struct Other 中 Field 的值;
    • ltcsfield=Other.Field: 必须小于 struct Other 中 Field 的值;
    • ltecsfield=Other.Field: 必须小于等于 struct Other 中 Field 的值;

    示例

    package main
    
    import (
    	"log"
    
    	"github.com/go-playground/validator"
    )
    
    type Student struct {
    	Name     string `validate:"required,eqcsfield=Pen.StudentName"`  // eqcsfield:Name的值必须等于Pen.StudentName的值
    	Passwd   string `validate:"required,max=20,min=6"`
    	Repasswd string `validate:"required,max=20,min=6,eqfield=Passwd"` // eqfield必须等于passwd的值
    	Pen      struct {
    		StudentName string `validate:"required"`
    	}
    }
    
    func student() {
    	student := Student{
    		Name:     "ysm",
    		Passwd:   "123456",
    		Repasswd: "123456",
    		Pen: struct {
    			StudentName string `validate:"required"`
    		}{StudentName: "ysm"},
    	}
    	log.Printf("student:%+v
    ", student)
    	validate := validator.New()
    	validatErr := validate.Struct(&student)
    	errs := make([]validator.FieldError, 0)
    	if validatErr != nil {
    		for _, err := range validatErr.(validator.ValidationErrors) {
    			errs = append(errs, err)
    		}
    	}
    	if len(errs) != 0 {
    		for i := 0; i < len(errs); i++ {
    			log.Println(errs[i])
    		}
    	}
    }
    
    func main(){
    	student()
    }
    

    自定义类型

    • 主要使用validator.New().RegisterValidation("tagName",tagFunc)

    示例

    package main
    
    import (
    	"log"
    
    	"github.com/go-playground/validator"
    )
    
    type Users struct {
    	Phone  string `validate:"required,PhoneValidationErrors"` // 必填
    	Email  string `validate:"email"`                          // 验证字符串是email格式。默认为必填
    	Url    string `validate:"url"`                            // 验证字符串是URL格式。默认为必填
    	Passwd string `validate:"required,max=20,min=6"`          // max字符串最大长度,min字符串最小长度
    	Code   string `validate:"required,len=6"`                 // len字符串长度必须为n,或者是数组、切片、map的len的值
    	Eq     int    `validate:"eq=4"`                           // eq数字等于n
    	Ne     int    `validate:"ne=4"`                           // ne数字不等n
    	Gt     int    `validate:"gt=4"`                           // gt数字大于n
    	Gte    int    `validate:"gte=4"`                          // gte数字大于等于n
    	Lt     int    `validate:"lt=4"`                           // lt小于n
    	Lte    int    `validate:"lte=4"`                          // lte小于等于
    }
    func main() {
    	users := Users{
    		Phone:  "13345679878",
    		Email:  "1843121593@qq.com",
    		Url:    "https://blog.csdn.net/guyan0319/article/details/105918559",
    		Passwd: "123456",
    		Code:   "123456",
    		Eq:     4,
    		Ne:     3,
    		Gt:     5,
    		Gte:    4,
    		Lt:     3,
    		Lte:    4,
    	}
    	log.Printf("users:%+v
    ", users)
    	validate := validator.New()
    	// 注册自定义函数
    	_ = validate.RegisterValidation("PhoneValidationErrors", PhoneValidationErrors)
    	validatErr := validate.Struct(&users)
    	errs := make([]validator.FieldError, 0)
    	if validatErr != nil {
    		for _, err := range validatErr.(validator.ValidationErrors) {
    			errs = append(errs, err)
    		}
    	}
    	if len(errs) != 0 {
    		for i := 0; i < len(errs); i++ {
    			log.Println(errs[i])
    		}
    	}
    }
    
    // 返回TRUE则不会报错,返回FALSE则会报错
    func PhoneValidationErrors(fl validator.FieldLevel) bool {
    	return fl.Field().String() == "13345679878"
    }
    
  • 相关阅读:
    密码验证合格程序(Python)
    Python找到所有子集
    Semi-Supervised Classification with Graph Convolutional Networks 阅读笔记
    2018 ICPC南京网络赛 L Magical Girl Haze 题解
    2018 CCPC网络赛 hdu6444 Neko's loop
    2018 CCPC 网络赛 Buy and Resell
    实对称矩阵可对角化证明
    矩阵的极分解证明
    关于欧几里得空间上的仿射变换的直观几何理解
    Codeforces Hello 2018 E题Logical Expression dp+最短路 好题
  • 原文地址:https://www.cnblogs.com/MyUniverse/p/15227003.html
Copyright © 2011-2022 走看看