1.安装validator
go get -u github.com/go-playground/validator/v10
2.使用
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
//"gopkg.in/go-playground/validator.v10"
"net/http"
)
type User struct{
UserName string `validate:"min=3,max=13"`
Password string `validate:"min=3,max=13"`
}
func main() {
u := User{UserName: "z"}
validate := validator.New()
fmt.Println(u)
err := validate.Struct(u)
fmt.Println("err:",err)
}
错误提示
{z }
err: Key: 'User.UserName' Error:Field validation for 'UserName' failed on the 'min' tag
Key: 'User.Password' Error:Field validation for 'Password' failed on the 'min' tag
3.校验规则
len:length 等于,长度相等
max:小于等于
min:大于等于
eq:等于,字符串相等
ne:不等于
gt:大于
gte:大于等于
lt:小于
lte:小于等于,例如lte=10;
oneof:值中的一个,例如oneof=1 2
支持时间范围的比较lte
时间 RegTime time.Time `validate:"lte"` 小于等于当前时间
跨字段约束
eqfield=ConfirmPassword
eqcsfield=InnerStructField.Field
字符串规则
contains=:包含参数子串
containsany:包含参数中任意的 UNICODE 字符
containsrune:包含参数表示的 rune 字符
excludes:不包含参数子串
excludesall:不包含参数中任意的 UNICODE 字符
excludesrune:不包含参数表示的 rune 字符
startswith:以参数子串为前缀
endswith:以参数子串为后缀
使用unqiue来指定唯一性约束,对不同类型的处理如下:
对于数组和切片,unique约束没有重复的元素;
对于map,unique约束没有重复的值;
对于元素类型为结构体的切片,unique约束结构体对象的某个字段不重复,通过unqiue=name
特殊规则
-:跳过该字段,不检验;
|:使用多个约束,只需要满足其中一个,例如rgb|rgba;
required:字段必须设置,不能为默认值;
omitempty:如果字段未设置,则忽略它。
4.自定义规则及自定义提示信息
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
"log"
"reflect"
//"gopkg.in/go-playground/validator.v10"
"net/http"
)
type User struct{
UserName string `validate:"minReg" reg_error_info:"用户名至少6个字符"` //通过reg_error_info标签记录
//reg_error_info也可以是标记错误的唯一标识,通过传入的local_language 从库中或者缓存中找到对应国家的错误提示信息
Password string `validate:"minReg" reg_error_info:"密码至少6个字符"`
}
//自定义的校验规则,可以使用正则表达式进行匹配,这里仅仅使用了长度判断
func minRegFun(f validator.FieldLevel) bool {
value := f.Field().String()
log.Println(f)
if len(value) < 6 {
return false
}else {
return true
}
}
func main() {
u := User{UserName: "zzzzzz",Password: "xxxx"}
validate := validator.New()
validate.RegisterValidation("minReg", minRegFun) //注册自定义的校验函数 minReg和validate tag值保持一致
err := validate.Struct(u) //校验
errorInfo := processErr(u, err) //处理错误信息
if len(errorInfo) != 0 {
log.Println(errorInfo)
} else {
log.Println("校验通过")
}
}
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("reg_error_info") //获取field对应的reg_error_info tag值
return fieldName + ":" + errorInfo //返回错误
}else {
return "缺失reg_error_info"
}
}
return ""
}
结果
校验通过
2021/08/03 10:10:15 Password:密码至少6个字符