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
    })
}

  

 

 

 

 

 

posted @   wanghhhh  阅读(157)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2019-10-31 python 闯关之路一(语法基础)

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示