范围验证: 切片、数组和map、字符串,验证其长度;数值,验证大小范围
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
type User struct {
Name string `form:"name" json:"name" validate:"required,CustomerValidation"` //注意:required和CustomerValidation之间不能有空格,否则panic。CustomerValidation:自定义tag-函数标签
Age uint8 ` form:"age" json:"age" validate:"gte=0,lte=80"` //注意:gte=0和lte=80之间不能有空格,否则panic
}
var validate *validator.Validate
func main() {
validate = validator.New()
validate.RegisterValidation("CustomerValidation", CustomerValidationFunc) //注册自定义函数,前一个参数是struct里tag自定义,后一个参数是自定义的函数
user := &User{
Name: "jimmy",
Age: 86,
}
fmt.Println("first value: ", user)
err := validate.Struct(user)
if err != nil {
fmt.Printf("Err(s):\n%+v\n", err)
}
user.Name = "tom"
user.Age = 29
fmt.Println("second value: ", user)
err = validate.Struct(user)
if err != nil {
fmt.Printf("Err(s):\n%+v\n", err)
}
}
// 自定义函数
func CustomerValidationFunc(f1 validator.FieldLevel) bool {
// f1 包含了字段相关信息
// f1.Field() 获取当前字段信息
// f1.Param() 获取tag对应的参数
// f1.FieldName() 获取字段名称
return f1.Field().String() == "jimmy"
}
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
type User struct {
FirstName string `json:firstname`
LastName string `json:lastname`
Age uint8 `validate:"gte=0,lte=130"`
Email string `validate:"required,email"`
FavouriteColor string `validate:"hexcolor|rgb|rgba"`
}
var validate *validator.Validate
func main() {
validate = validator.New()
validate.RegisterStructValidation(UserStructLevelValidation, User{})
user := &User{
FirstName: "",
LastName: "",
Age: 30,
Email: "TestFunc@126.com",
FavouriteColor: "#000",
}
err := validate.Struct(user)
if err != nil {
fmt.Println(err)
}
}
func UserStructLevelValidation(sl validator.StructLevel) {
user := sl.Current().Interface().(User)
if len(user.FirstName) == 0 && len(user.LastName) == 0 {
sl.ReportError(user.FirstName, "FirstName", "firstname", "firstname", "")
sl.ReportError(user.LastName, "LastName", "lastname", "lastname", "")
}
}
package main
import (
"database/sql"
"database/sql/driver"
"fmt"
"reflect"
"github.com/go-playground/validator/v10"
)
type DbBackedUser struct {
Name sql.NullString `validate:"required"`
Age sql.NullInt64 `validate:"required"`
}
var validate *validator.Validate
func main() {
validate = validator.New()
validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})
// build object for validation
x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}}
err := validate.Struct(x)
if err != nil {
fmt.Printf("Err(s):\n%+v\n", err)
}
}
func ValidateValuer(field reflect.Value) interface{} {
if valuer, ok := field.Interface().(driver.Valuer); ok {
val, err := valuer.Value()
if err == nil {
return val
}
// handle the error how you want
}
return nil
}
validate := validator.New()
func (v *Validate) Var(field interface{}, tag string) error
var emailTest string = "test@126.com"
err = validate.Var(emailTest, "email")
func (v *Validate) Struct(s interface{}) error
user := &User{
FirstName: "Badger",
LastName: "Smith",
Age: 135,
Email: "Badger.Smith@gmail.com",
Addresses: []*Address{address},
}
err := validate.Struct(user)
func (v *Validate) Var(field interface{}, tag string) error
sliceone := []string{"123", "onetwothree", "myslicetest", "four", "five"}
err := validate.Var(sliceone, "max=15,dive,min=4")
说明:如实例1,dive前面的是验证 len(sliceone) 最大长度为15,后面的时候验证sliceone内的每一个参数 长度最小为4
slicethree := [][]string{}
validate.Var(slicethree, "min=2,dive,len=2,dive,required")
validate.Var(slicethree, "min=2,dive,dive,required")
mapone = map[string]string{"one": "jimmmy", "two": "", "1234": "123"}
err := validate.Var(mapone, "gte=3,dive,keys,min=4,endkeys,required"
说明:gte=3是对len(mapone)的验证;min=4是对mapone中的key进行验证;required是对value进行验证
maptwo := map[[3]string]string{[3]string{"123","345","567"}:"123"}
validate.Var(maptwo, "gte=3,dive,keys,dive,eq=1|eq=3,endkeys,required")
if err != nil {
fmt.Println(err)
}
for _, err := range errs.(validator.ValidationErrors) {
fmt.Println(err.Error())
}
步骤:
实例:
package main
import (
"fmt"
"strings"
"github.com/go-playground/locales/en"
"github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
zhtrans "github.com/go-playground/validator/v10/translations/zh"
// entrans "github.com/go-playground/validator/v10/translations/en"
)
type Student struct {
Name string `validate:required`
Email string `validate:"email"`
Age int `validate:"max=30,min=12"`
}
func main() {
// 1.新建需要的语言
en := en.New() //英文翻译器
zh := zh.New() //中文翻译器
// 2.将语言配置到翻译器中
// 第一个参数是必填,如果没有其他的语言设置,就用这第一个
// 后面的参数是支持多语言环境(
// uni := ut.New(en, en) 也是可以的
// uni := ut.New(en, zh, tw)
uni := ut.New(en, zh)
// 3.获取需要的语言
trans, _ := uni.GetTranslator("zh")
student := Student{
Name: "tom",
Email: "testemal",
Age: 40,
}
validate := validator.New()
// 4.把翻译器注册到validate中
zhtrans.RegisterDefaultTranslations(validate, trans)
err := validate.Struct(student)
if err != nil {
// fmt.Println(err)
errs := err.(validator.ValidationErrors)
// 5.翻译错误信息
fmt.Println(removeStructName(errs.Translate(trans)))
fmt.Println(errs.Translate(trans))
}
}
func removeStructName(fields map[string]string) map[string]string {
result := map[string]string{}
for field, err := range fields {
result[field[strings.Index(field, ".")+1:]] = err
}
return result
}
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
zh_translations "github.com/go-playground/validator/v10/translations/zh"
"net/http"
)
type Person struct {
Name string `form:"name" binding:"max=30,ne=Admin"`
Age int `form:"age" binding:"max=200,min=0"`
Sex string `form:"sex" binding:"oneof=woman man"`
}
func main() {
r := gin.Default()
r.Use(translation())
//_ = binding.Validator.Engine().(validator.Validate)
r.POST("/addPerson", func(ctx *gin.Context) {
trans, _ := ctx.Get("trans")
var person Person
err := ctx.ShouldBind(&person)
if err != nil {
errs := err.(validator.ValidationErrors)
ctx.JSON(http.StatusUnprocessableEntity, gin.H{
"msg": "failed",
"err": errs.Translate(trans.(ut.Translator)),
})
return
}
fmt.Println(person)
name := ctx.PostForm("name")
fmt.Println(name)
ctx.JSON(http.StatusOK, gin.H{"msg": "success"})
})
r.Run()
}
func translation() gin.HandlerFunc {
return func(ctx *gin.Context) {
//1. 新建需要的语言
zh := zh.New()
//2. 将语言配置到翻译器中
uni := ut.New(zh)
//3. 获取需要的语言
trans, _ := uni.GetTranslator("zh")
//4. 获取validator
v := binding.Validator.Engine().(*validator.Validate)
_ = zh_translations.RegisterDefaultTranslations(v, trans)
ctx.Set("trans", trans)
ctx.Next()
}
}