目录

Go Web validator 参数校验

Go Web validator 参数校验

Validator

validator Fields

TagDescription
eqcsfieldField Equals Another Field (relative)
eqfieldField Equals Another Field
fieldcontainsNOT DOCUMENTED IN doc.go
fieldexcludesNOT DOCUMENTED IN doc.go
gtcsfieldField Greater Than Another Relative Field
gtecsfieldField Greater Than or Equal To Another Relative Field
gtefieldField Greater Than or Equal To Another Field
gtfieldField Greater Than Another Field
ltcsfieldLess Than Another Relative Field
ltecsfieldLess Than or Equal To Another Relative Field
ltefieldLess Than or Equal To Another Field
ltfieldLess Than Another Field
necsfieldField Does Not Equal Another Field (relative)
nefieldField Does Not Equal Another Field
  • 注意: 一般来说 Struct 的结构体 tag 使用 validate 进行约束. 在 Gin 框架中, 使用 binding 就可以约束。

Gin 框架使用例子

翻译器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package validator

import (
	"fmt"

	"github.com/gin-gonic/gin/binding"
	"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"
	enTranslations "github.com/go-playground/validator/v10/translations/en"
	zhTranslations "github.com/go-playground/validator/v10/translations/zh"
)

// validator 翻译器

// 定义一个全局的翻译器 trans
var trans ut.Translator

// 初始化翻译器
func InitTrans(locale string) (err error) {
	// 更改Gin框架中validator引擎的属性,实现翻译
	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {

		// 注册一个获取 json tag 的自定义方法
		v.RegisterTagNameFunc(func(field reflect.StructField) string {
			name := strings.SplitN(field.Tag.Get("json"), ",", 2)[0]
			if name == "-" {
				return ""
			}
			return name
		})

		// 中文
		zhT := zh.New()
		// 英文
		enT := en.New()

		uni := ut.New(enT, zhT, enT)

		// locale 取决于 http 请求中的 'Accept-Language' 决定
		var ok bool
		trans, ok = uni.GetTranslator(locale)
		if !ok {
			return fmt.Errorf("uni.GetTranslator(%s) Failed", locale)
		}
		// 注册翻译器
		switch locale {
		case "en":
			err = enTranslations.RegisterDefaultTranslations(v, trans)
		case "zh":
			err = zhTranslations.RegisterDefaultTranslations(v, trans)
		default:
			err = enTranslations.RegisterDefaultTranslations(v, trans)
		}
		return
	}
	return
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

// 定义请求参数的结构体
type ParamSignUp struct {
	UserName   string `json:"username" binding:"required"`
	Password   string `json:"password" binding:"required"`
	RePassword string `json:"re_password" binding:"required"`
}

func main() {
        // 初始化 validator 翻译器

	if err := validator.InitTrans("zh"); err!=nil {
            fmt.Println("InitTrans Failed Error", err)
            return
	}
	r := gin.Default()

	r.POST("/signup", func(c *gin.Context) {
		var p ParamSignUp
		if err := c.ShouldBind(&p); err != nil {
                   // 判断这个错误是否属于 vilidator 类型校检错误。
		   verr, ok := err.(vilidator.ValidationErrors)
                   if !ok {
		   // 如果不是 vilidator 类型错误就返回正常的错误类型
                      c.JSON(http.StatusOK, gin.H{
                                "Msg": err.Error(),
                    })
		    return
		  }
                  // 如果是 vilidator 类型错误
		   c.JSON(http.StatusOK, gin.H{
		           "Msg": verr.Translate(trans),
		})
		return
	     }
	})
	r.Run()
}