gin表单验证
一. 表单验证的初始化
1. 定义forms验证
在forms目录下创建user.go文件
增加验证的struct内容
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文件,并且定义初始化翻译功能
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入口文件进行初始化,增加如下内容
//初始化翻译
if err := initialize.InitTrans("zh"); err != nil {
panic(err)
}
全部内容
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文件中使用验证器
增加密码验证的接口
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
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函数中注册验证器
//注册验证器
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
_ = v.RegisterValidation("mobile", myvalidator.ValidateMobile)
}
3.在form表单中加入mobile,和上述 注册的时候填写的一样
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.以上会出现一个问题,报错提示还是英文
解决办法
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
})
}

浙公网安备 33010602011771号