validator 单个字段格式验证
先来一个单个字段格式的验证
目录结构
在main函数中
package mainimport "awesomeProject/validate"func main() {validate.SingleFieldValidate()
}
在validator.go中
package validateimport ("github.com/go-playground/validator/v10""log"
)var validate *validator.Validatefunc init() {validate = validator.New()validate.SetTagName("v")}func outRes(tag string, err *error) {log.Println("---------------------start" + tag + "----------------------")log.Println(*err)log.Println("---------------------end " + tag + "----------------------")err = nil
}
在single_field.go中
package validate//bool
//number
//string
//Slices//set//timefunc SingleFieldValidate() {v := validatevar err errorvar b boolerr = v.Var(b, "boolean")outRes("boolean", &err)var i = "100"err = v.Var(i, "number")outRes("number", &err)}
所得结果:
说明验证正确,返回了nil
而对于
var i = "100"err = v.Var(i, "number")outRes("number", &err)var f = "100.12"err = v.Var(f, "numeric")outRes("numeric", &err)
对于数字类型的字符串,需要用numeric来校验(它可以校验小数点)
如果表示字符串,而是直接是数字,那么number和numeric就没有区别
通过
var slice = []int{1, 2, 3, 4, 5, 6, 7, 8, 9,}err = v.Var(slice, "max=15,min=2")outRes("slice", &err)
可以验证slice的长度,至于内容,看本文第三节
还有其他类型的格式验证
var timeStr = time.Now().Format("2006-01-02 15:04:05")err = v.Var(timeStr, "datetime=2006-01-02 15:04:05")outRes("time", &err)s1 := "abc"s2 := "abc"err = v.VarWithValue(s1, s2, "eqfield")outRes("eqfield", &err)i1 := 10i2 := 20err = v.VarWithValue(i1, i2, "ltfield")outRes("ltfield", &err)
validator 结构绑定格式验证
先创建struct.go文件来保存我们的结构体
package validatetype User struct {Name stringAge intPhone stringEmail stringFavoriteColor1 stringFavoriteColor2 stringAddress *AddressContactUser []*ContactUserHobby []string
}type Address struct {Province stringCity string
}type ContactUser struct {Name stringAge uint8Phone stringEmail stringAddress *Address
}
最开始我们在validate.go中设置了一个v
validate.SetTagName("v")
使用v来设置验证要求
package validatetype User struct {Name string `v:"required,alphaunicode"`Age int `v:"gte=10,lte=30"`Phone string `v:"required,e164"`Email string `v:"required,email"`FavoriteColor1 string `v:"iscolor"`FavoriteColor2 string `v:"hexcolor|rgb|rgba|hsl|hsla"`Address *Address `v:"required"`ContactUser []*ContactUser `v:"required,get=1,dive"`Hobby []string `v:"required,gte=2,dive,required,gte=2,alphaunicode"`
}type Address struct {Province string `v:"required"`City string `v:"required"`
}type ContactUser struct {Name string `v:"required,alphaunicode"`Age uint8 `v:"gte=20,lte=130"`Phone string `v:"required_without_all=Email Address,omitempty,e164"`Email string `v:"required_without_all=Phone Address,omitempty,email"`Address *Address `v:"required_without_all=Phone Email"`
}
补充测试代码
err := v.Struct(user)if err != nil {if errors, ok := err.(validator.ValidationErrors); ok {for _, err := range errors {fmt.Println(err)
调用测试
package mainimport "awesomeProject/validate"func main() {validate.StructValidate()
}
没有如何显示,说明没有任何错误
注:通过dive表明要进一步验证切片內部验证有没有通过
切片与集合内元素格式验证
验证slice
package validatefunc SliceValidate(){v:=validateslice1:=[]string{"12345","6789","12345678"}var err errorerr = v.Var(slice1,"gte=3,dive,required,gte=5,lte=10,number")outRes("slice",&err)
}
gte=3表示切片数量大于等于3,
dive,切片内部元素检验
gte=5,lte=10,number ---- 是大于等于5小于等于10的数字
package mainimport "awesomeProject/validate"func main() {//validate.SingleFieldValidate()//validate.StructValidate()validate.SliceValidate()
}
验证
报错
说是索引为一的位置没有大于等于5
确实6789只有四个数字
测试二维切片
slice2 := [][]string{{"12345", "12345", "69889", "12345678"},{"12345", "6789", "12345678"},{"12345", "12345", "69889", "12345678"},}err = v.Var(slice2, "gte=3,dive,required,gte=5,lte=10,number")outRes("slice", &err)
意思说,虽然 err = v.Var(slice2, "gte=3,dive,required,gte=5,lte=10,number")
中第一个满足了第一维度有3个,但是第二维度大于5个则都不满足
将5改成3
err = v.Var(slice2, "gte=3,dive,required,gte=3,lte=10,number")
报错不是number了,改成字符串
完成
再验证,slice里面放的是对象
type sliceStruct struct {OpCode int `v:"eq=1|eq=2"`Op string `v:"required"`
}slice3 := []*sliceStruct{{OpCode: 1,Op: "切片操作",},{OpCode: 2,Op: "切片操作",},{OpCode: 3,Op: "切片操作",},}err = v.Var(slice3, "gte=2,dive")outRes("slice3", &err)
可以看到,第三个报错,OpCode只能是1或者2
验证无误
接下来我们看map
func MapValidates() {v := validatevar err errormp1 := map[string]string{"A": "12345","B": "6789","C": "12345678",}err = v.Var(mp1, "gte=3,dive,keys,len=1,alpha,endkeys,required,gte=4,lte=10,number")outRes("map", &err)}
当我们从map进入dive之后,就会发现有两个值key和value,可以先验证key再验证value
gte=3,dive, keys,len=1,alpha,endkeys,required,gte=4,lte=10,number
成功
我们再来试一试map的嵌套
mp2 := map[string]map[string]string{"A": {"A": "12345","B": "6789","C": "12345678",},"B": {"A": "12345","B": "6789","C": "12345678",},"C": {"A": "12345","B": "6789","C": "12345678",},}err = v.Var(mp2, "gte=3,dive,keys,len=1,alpha,endkeys,required,gte=3,dive,keys,len=1,alpha,endkeys,gte=2,lte=10,number")outRes("map2", &err)
此时value部分是我们的map
我们可以直接dive进入map
之后就和一层map是一样的
准确无误