Go Gin:Validator参数验证

597 阅读1分钟

「本文正在参加金石计划

  1. 下载

    go get github.com/go-playground/validator/v10

  2. 为结构体添加validate标签

    type User struct {
    	Name    string  `validate:"require,len=12"`
    	Age     uint8   `validate:"gte=0,lte=130"`
    	Gender  uint8   `validate:"oneof=0 1"`
    	Email   string  `validate:"required,email"`
    	Address Address `validate:"required,dive,required"`
    }
    
    type Address struct {
    	Country  string `validate:"required"`
    	Province string `validate:"required"`
    	City     string `validate:"required"`
    	Street   string `validate:"required"`
    }
    

    常用的标签

    Comparisons:
    TagDescriptionUsage
    eq=`validate:"eq=1"`
    gt>`validate:"gt=0"`
    gte>=`validate:"gte=0"`
    lt<`validate:"lt=130"`
    lte<=`validate:"lte=130"`
    ne!=`validate:"ne=38"`
    Other:
    TagDescriptionUsage
    required是否必须`validate:"required"`
    len设置长度`validate:"len=9"`
    max最大值`validate:"max=100"`
    min最小值`validate:"min=1"`
    oneof值只能是多少(区间内)`validate:"oneof=0 1"` // 0或1
  3. 生成

    addr1 := Address{
      Country:  "China",
      Province: "GuangDong",
      City:     "GuangZhou",
      Street:   "DongFang Street",
    }
    u1 := User{
      Name:    "Catlinie",
      Age:     135,
      Gender:  1,
      Email:   "1388888888@qq.com",
      Address: &addr1,
    }
    err := validate.Struct(&user)
    if err != nil{
    	validationErrors, ok := err.(validator.ValidationErrors)
         if !ok{
            panic("validationError")
         }
      ...
    }
    
  4. 与Gin配合

    此时不需要单独重新封装validator,因为Gin的参数校验使用的就是它。在我们每次使用ShouldBind()的时候,Gin底层都会使用validate.Struct()。在Gin中,用户不使用validate Tag而是binding Tag

    type TestAPI struct {
    	ID     uint   `form:"id"`
    	Name   string `form:"name" binding:"required"`
    	Age    uint   `form:"age" binding:"required,min=0,max=120"`
    	Gender uint8  `form:"gender,default=1" binding:"oneof=0 1"`
    	Desc   string `form:"desc"`
    }
    
    func main(){
    	r := gin.Default()
      
    	r.GET("/ping", func(context *gin.Context) {
    		t := TestAPI{}
    		err := context.ShouldBind(&t)
    		if err != nil {
    			errs, ok := err.(validator.ValidationErrors)
    			if !ok {
    				// ...
    				return
    			}
    			// 输出错误
          // validator允许用户添加翻译器
    			return
    		}
    		// 后续操作
    	})
    
    	r.Run(":8000")
    }
    
  5. 错误翻译本地化

    1. 获取翻译器组

      import(
        zh "github.com/go-playground/locales/zh"
        en "github.com/go-playground/locales/en"
        ut "github.com/go-playground/universal-translatior"
      )
      
      uni := ut.New(zh.New(), en.New())
      
    2. 获取指定翻译器

      trans, _ := uni.GetTranslator("zh")

    3. 将翻译器注册进validator里

      import zh_translations "github.com/go-playground/validator/v10/translations/zh"
      
      zh_translations.RegisterDefaultTransltions(validate, trans)
      
    4. 翻译

      err := validate.Struct(user)
      if err != nil{
        errs, ok := err.(validator.ValidationErrors)
        if !ok{
          return
        }
        fmt.Println(errs.Translate(trans))
      }