package validator import ( "reflect" "strings" "sync" "github.com/gin-gonic/gin/binding" "github.com/go-playground/locales/en" ut "github.com/go-playground/universal-translator" "gopkg.in/go-playground/validator.v9" en_translations "gopkg.in/go-playground/validator.v9/translations/en" ) var ( ValidatorUni *ut.UniversalTranslator ) type defaultValidator struct { once sync.Once validate *validator.Validate } var v binding.StructValidator = &defaultValidator{} func init() { v.Engine() } func (v *defaultValidator) ValidateStruct(obj interface{}) error { if kindOfData(obj) == reflect.Struct { v.lazyinit() if err := v.validate.Struct(obj); err != nil { return error(err) } } return nil } func (v *defaultValidator) Engine() interface{} { v.lazyinit() return v.validate } func (v *defaultValidator) lazyinit() { v.once.Do(func() { v.validate = validator.New() // 依旧使用bingding tag兼容v8 v.validate.SetTagName("binding") // 错误信息转换 en := en.New() ValidatorUni = ut.New(en, en) trans, _ := ValidatorUni.GetTranslator("en") en_translations.RegisterDefaultTranslations(v.validate, trans) v.validate.RegisterTagNameFunc(func(fld reflect.StructField) string { name := strings.SplitN(fld.Tag.Get("comment"), ",", 2)[0] if name == "-" { return "" } return name }) }) } func kindOfData(data interface{}) reflect.Kind { value := reflect.ValueOf(data) valueType := value.Kind() if valueType == reflect.Ptr { valueType = value.Elem().Kind() } return valueType }