validator 单个字段格式验证
先来一个单个字段格式的验证
目录结构
在main函数中
package main
import "awesomeProject/validate"
func main() {
validate.SingleFieldValidate()
}
在validator.go中
package validate
import (
"github.com/go-playground/validator/v10"
"log"
)
var validate *validator.Validate
func 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
//time
func SingleFieldValidate() {
v := validate
var err error
var b bool
err = 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 := 10
i2 := 20
err = v.VarWithValue(i1, i2, "ltfield")
outRes("ltfield", &err)
validator 结构绑定格式验证
先创建struct.go文件来保存我们的结构体
package validate
type User struct {
Name string
Age int
Phone string
Email string
FavoriteColor1 string
FavoriteColor2 string
Address *Address
ContactUser []*ContactUser
Hobby []string
}
type Address struct {
Province string
City string
}
type ContactUser struct {
Name string
Age uint8
Phone string
Email string
Address *Address
}
最开始我们在validate.go中设置了一个v
validate.SetTagName("v")
使用v来设置验证要求
package validate
type 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 main
import "awesomeProject/validate"
func main() {
validate.StructValidate()
}
没有如何显示,说明没有任何错误
注:通过dive表明要进一步验证切片內部验证有没有通过
切片与集合内元素格式验证
验证slice
package validate
func SliceValidate(){
v:=validate
slice1:=[]string{"12345","6789","12345678"}
var err error
err = 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 main
import "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 := validate
var err error
mp1 := 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是一样的
准确无误