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

  

 

 

 

 

 

posted @ 2022-10-31 14:05  wanghhhh  阅读(169)  评论(0)    收藏  举报