参考go语言编程之旅博客开发一章,把gin validator验证翻译器做成中间件放到r.Use(middleware.Translations())里当后台访问比较频繁的时候会直接panic 提示bad map state 和concurrent map write。这种情况下怎么解决 新人求教
gin自带了validator.Validate,你只需要把翻译器注册进去就可以了,不需要用中间件处理这个东西。
中间件是处理每个request的功能,就像servlet中的filter功能。也可以理解为每个handler外部包了一层逻辑处理
#7
更多评论
`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