把gin validator验证翻译器组成中间件访问频繁会造成panic concurrent map write

cuiyuanxin · · 1746 次点击
`package middleware import ( "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/go-playground/locales/en" "github.com/go-playground/locales/zh" "github.com/go-playground/locales/zh_Hant_TW" ut "github.com/go-playground/universal-translator" validator "github.com/go-playground/validator/v10" en_translations "github.com/go-playground/validator/v10/translations/en" zh_translations "github.com/go-playground/validator/v10/translations/zh" "regexp" ) // Func myvalidator.ValidateMobile type Func func(fl validator.FieldLevel) bool // RegisterValidatorFunc 注册自定义校验tag func RegisterValidatorFunc(v *validator.Validate, trans ut.Translator, tag string, msg string, fn Func) { // 注册tag自定义校验 _ = v.RegisterValidation(tag, validator.Func(fn)) //自定义错误内容 _ = v.RegisterTranslation(tag, trans, func(ut ut.Translator) error { return ut.Add(tag, "{0}"+msg, true) // see universal-translator for details }, func(ut ut.Translator, fe validator.FieldError) string { t, _ := ut.T(tag, fe.Field()) return t }) return } // ValidateMobile 校验手机号 func ValidateMobile(fl validator.FieldLevel) bool { // 利用反射拿到结构体tag含有mobile的key字段 mobile := fl.Field().String() //使用正则表达式判断是否合法 ok, _ := regexp.MatchString(`^1[3456789]{1}\d{9}$`, mobile) if !ok { return false } return true } func Translations() gin.HandlerFunc { return func(c *gin.Context) { uni := ut.New(en.New(), zh.New(), zh_Hant_TW.New()) locale := c.GetHeader("locale") trans, _ := uni.GetTranslator(locale) v, ok := binding.Validator.Engine().(*validator.Validate) if ok { RegisterValidatorFunc(v, trans, "checkMobile", "输入格式不正确", ValidateMobile) switch locale { case "zh": _ = zh_translations.RegisterDefaultTranslations(v, trans) break case "en": _ = en_translations.RegisterDefaultTranslations(v, trans) break default: _ = zh_translations.RegisterDefaultTranslations(v, trans) break } c.Set("trans", trans) } c.Next() } } `
#2
更多评论
中间件源码发出来看看
#1
是这个中间件的原因吗,你发的代码这个中间件已经注释了。根据报错来看,是因为并发的写入map。不能多线程同时写入。
#3