gin表单验证
一. 表单验证的初始化
1. 定义forms验证
在forms目录下创建user.go文件
增加验证的struct内容
1 2 3 4 5 6 | package forms type PassWordLoginForm struct { Mobile string `form: "mobile" json: "mobile" binding: "required" ` //手机号码规则验证,自定义validator PassWord string `form: "password" json: "password" binding: "required,min=3.max=20" ` } |
2. 创建validator.go文件,并且定义初始化翻译功能
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 | package initialize import ( "fmt" "mxshop-api/user-web/global" "reflect" "strings" "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" en_translations "github.com/go-playground/validator/v10/translations/en" zh_translations "github.com/go-playground/validator/v10/translations/zh" ) func InitTrans(locale string) (err error) { //修改gin框架中的validator引擎属性, 实现定制 if v, ok := binding.Validator.Engine().(*validator.Validate); ok { //注册一个获取json的tag的自定义方法 v.RegisterTagNameFunc( func (fld reflect.StructField) string { name := strings.SplitN(fld.Tag.Get( "json" ), "," , 2)[0] if name == "-" { return "" } return name }) zhT := zh.New() //中文翻译器 enT := en.New() //英文翻译器 //第一个参数是备用的语言环境,后面的参数是应该支持的语言环境 uni := ut.New(enT, zhT, enT) global.Trans, ok = uni.GetTranslator(locale) if !ok { return fmt.Errorf( "uni.GetTranslator(%s)" , locale) } switch locale { case "en" : en_translations.RegisterDefaultTranslations(v, global.Trans) case "zh" : zh_translations.RegisterDefaultTranslations(v, global.Trans) default : en_translations.RegisterDefaultTranslations(v, global.Trans) } return } return } |
3. 初始化翻译
在main.go入口文件进行初始化,增加如下内容
1 2 3 4 | //初始化翻译 if err := initialize.InitTrans( "zh" ); err != nil { panic(err) } |
全部内容
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 | package main import ( "fmt" "go.uber.org/zap" "mxshop-api/user-web/global" "mxshop-api/user-web/initialize" ) func main() { //初始化logger initialize.InitLogger() //初始化配置文件 initialize.InitConfig() //初始化routes Router := initialize.Routers() //初始化翻译 if err := initialize.InitTrans( "zh" ); err != nil { panic(err) } /* 1. S()可以获取一个全局的sugar,可以让我们自己设置一个全局的logger 2. 日志是分级别的,debug, info , warn, error, fetal 3. S函数和L函数很有用, 提供了一个全局的安全访问logger的途径 */ zap.S().Infof( "启动服务" ) //port := 8881 if err := Router.Run(fmt.Sprintf( ":%d" , global.ServerConfig.Port)); err != nil { zap.S().Panic( "启动失败:" , err.Error()) } } |
4. 在api接口 user.go文件中使用验证器
增加密码验证的接口
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 | func HandleValidatorError(ctx *gin.Context, err error) { //定义统一返回的报错处理 errs, ok := err.(validator.ValidationErrors) if !ok { ctx.JSON(http.StatusOK, gin.H{ "msg" : err.Error(), }) } ctx.JSON(http.StatusBadRequest, gin.H{ "error" : removeTopStruct(errs.Translate(global.Trans)), }) return } func PassWordLogin(ctx *gin.Context) { //密码登录的接口 //1.表单验证, 在forms中定义 //ctx.JSON(http.StatusOK, "密码登录") passWordLoginForm := forms.PassWordLoginForm{} //固定格式 if err := ctx.ShouldBind(&passWordLoginForm); err != nil { HandleValidatorError(ctx, err) return } } |
二. 表单验证-自定义Mobile的验证器
1. 定义验证器, 在validator中创建文件validators.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package validator import ( "regexp" "github.com/go-playground/validator/v10" ) func ValidateMobile(fl validator.FieldLevel) bool { mobile := fl.Field().String() //使用正则表达式判断是否合法 ok, _ := regexp.MatchString(`^1([38][0-9]|14[579]|5[^4]|16[6]|7[1-35-8]|9[189])\d{8}$`, mobile) if !ok { return false } return true } |
2. 在main函数中注册验证器
1 2 3 4 | //注册验证器 if v, ok := binding.Validator.Engine().(*validator.Validate); ok { _ = v.RegisterValidation( "mobile" , myvalidator.ValidateMobile) } |
3.在form表单中加入mobile,和上述 注册的时候填写的一样
1 2 3 4 5 6 | package forms type PassWordLoginForm struct { Mobile string `form: "mobile" json: "mobile" binding: "required,mobile" ` //手机号码规则验证,自定义validator PassWord string `form: "password" json: "password" binding: "required,min=3,max=20" ` } |
4.以上会出现一个问题,报错提示还是英文
解决办法
1 2 3 4 5 6 7 8 9 | if v, ok := binding.Validator.Engine().(*validator.Validate); ok { _ = v.RegisterValidation( "mobile" , myvalidator.ValidateMobile) _ = v.RegisterTranslation( "mobile" , global.Trans, func (ut ut.Translator) error { return ut.Add( "mobile" , "{0} 非法的手机号码!" , true) // see universal-translator for details }, func (ut ut.Translator, fe validator.FieldError) string { t, _ := ut.T( "mobile" , fe.Field()) return t }) } |