每日一库golang validator常规参数校验及自定义规则校验,自定义返回中文错误信息

作者: adm 分类: go 发布时间: 2023-07-23

1.validator简介
validator是一个开源的验证器包,可以快速校验输入信息是否符合自定规则。源码地址: https://github.com/go-playground/validator

本地开发安装库:

go get github.com/go-playground/validator

示例用户名与密码校验

package main
 
import (
	"fmt"
	"github.com/go-playground/validator/v10"
	"reflect"
	"regexp"
)
 
 
func main()  {
	u := User{
		Username: "IamJames",
		Password: "1234567A$888",
	}
	validate := validator.New()
	_ = validate.RegisterValidation("minLen", minLen)
	_ = validate.RegisterValidation("verifyPwd", verifyPwd)
	err := validate.Struct(u)
	if err != nil {
		errInfo := processErr(u, err)
		fmt.Printf("error: %v\n", err)
		fmt.Printf("errorInfo: %v\n", errInfo)
		return
	}
	fmt.Println("validate pass...")
}
 
type User struct {
	Username string `json:"username,omitempty" validate:"required,minLen" field_error_info:"用户名最少6个字符"`
	Password string `json:"password,omitempty" validate:"required,verifyPwd" field_error_info:"密码应包含数字、大/小写字母、特殊字符中的3种, 且至少8个字符"`
        Email    string   `json:"email" validate:"required,email"`			     // 限于email格式
	Phone    string   `json:"phone" validate:"omitempty,numeric"`		     // 限于数字型
	Hobby	 []string `json:"hobby" validate:"omitempty"` 				     // 空时忽略
	Age 	 int      `json:"age" validate:"omitempty,gt=18,lt=100"`		 // 限制大小
	Gender   string	  `json:"gender" validate:"omitempty,oneof=male female"` // 限于男女
        Nickname string   `json:"nickname" validate:"required,min=4,max=20"`     // 必填字段,限制长度
}
 
func minLen(f validator.FieldLevel) bool {
	val := f.Field().String()
	if len(val) < 6 {
		return false
	}
	return true
}
 
func verifyPwd(f validator.FieldLevel) bool {
	val := f.Field().String()
	if len(val) < 8 || len(val) > 20 { // length需要通过验证
		fmt.Println("pwd length error")
		return false
	}
 
	pwdPattern := `^[0-9a-zA-Z!@#$%^&*~-_+]{8,20}$`
	reg, err := regexp.Compile(pwdPattern) // filter exclude chars
	if err != nil {
		return false
	}
 
	match := reg.MatchString(val)
	if !match {
		fmt.Println("not match error.")
		return false
	}
 
	var cnt int = 0 // 满足3中以上即可通过验证
	patternList := []string{ // 数字、大小写字母、特殊字符
		`[0-9]+`,
		`[a-z]+`,
		`[A-Z]+`,
		`[!@#$%^&*~-_+]+`,
	}
	for _, pattern := range patternList {
		match, _ = regexp.MatchString(pattern, val)
		if match {
			cnt++
		}
	}
	if cnt < 3 {
		fmt.Println("pwd should include at least 3 types.")
		return false
	}
	return true
}
 
func processErr(u interface{},err error) string {
	if err == nil {  //如果为nil 说明校验通过
		return ""
	}
 
	invalid, ok := err.(*validator.InvalidValidationError)   //如果是输入参数无效,则直接返回输入参数错误
	if ok {
		return "输入参数错误:" + invalid.Error()
	}
	validationErrs := err.(validator.ValidationErrors)   //断言是ValidationErrors
	for _, validationErr := range validationErrs {
		fieldName := validationErr.Field()              //获取是哪个字段不符合格式
		field, ok := reflect.TypeOf(u).FieldByName(fieldName)  //通过反射获取filed
		if ok {
			errorInfo := field.Tag.Get("field_error_info")  //获取field对应的reg_error_info tag值
			return fieldName + ": " + errorInfo  //返回错误
		}else {
			return "缺失field_error_info"
		}
	}
	return ""
}

返回信息

error: Key: 'User.Password' Error:Field validation for 'Password' failed on the 'verifyPwd' tag
errorInfo: Password: 密码应包含数字、大/小写字母、特殊字符中的3种, 且至少8个字符

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!