go-gin中实现binding验证器中文翻译

423 阅读1分钟

第一步 下载相关翻译依赖

go get github.com/go-playground/locales/zh

go get github.com/go-playground/universal-translator

go get github.com/go-playground/validator/v10

第二步 编写validator.go文件

package validator

import (
	"fmt"

	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	zh_translations "github.com/go-playground/validator/v10/translations/zh"
)

var validate *validator.Validate
var trans ut.Translator

func InitValidate() {
	fmt.Println("init validate初始化了")
	validate = validator.New()
	uni := ut.New(zh.New()) // 创建中文翻译器
	trans, _ = uni.GetTranslator("zh")  // 获取中文翻译器

	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
		// 注册中文翻译
		_ = zh_translations.RegisterDefaultTranslations(v, trans)

		// 自定义错误消息模板
		v.RegisterTranslation("required", trans, func(ut ut.Translator) error {
			return ut.Add("required", "{0} 是必填字段", true)
		}, func(ut ut.Translator, fe validator.FieldError) string {
			t, _ := ut.T("required", fe.Field())
			return t
		})
		// 自定义邮箱错误模板
		v.RegisterTranslation("email", trans, func(ut ut.Translator) error {
			return ut.Add("email", "{0} 不是有效的邮箱地址", true)
		}, func(ut ut.Translator, fe validator.FieldError) string {
			t, _ := ut.T("email", fe.Field())
			return t
		})
		// 自定义最小和最大长度错误模板
		v.RegisterTranslation("min", trans, func(ut ut.Translator) error {
			return ut.Add("min", "{0} 的长度不能小于 {1}", true)
		}, func(ut ut.Translator, fe validator.FieldError) string {
			t, _ := ut.T("min", fe.Field(), fe.Param())
			return t
		})

		v.RegisterTranslation("max", trans, func(ut ut.Translator) error {
			return ut.Add("max", "{0} 的长度不能大于 {1}", true)
		}, func(ut ut.Translator, fe validator.FieldError) string {
			t, _ := ut.T("max", fe.Field(), fe.Param())
			return t
		})
		v.RegisterTranslation("max", trans, func(ut ut.Translator) error {
			return ut.Add("alphanum", "{0} 只能包含字母和数字", true)
		}, func(ut ut.Translator, fe validator.FieldError) string {
			t, _ := ut.T("max", fe.Field())
			return t
		})
	}
}

func ValidateStruct(s interface{}) error {
	if err := validate.Struct(s); err != nil {
		return err
	}
	return nil
}
func TranslateValidationError(err error) string {
	errs := err.(validator.ValidationErrors)
	var errMsg string
	for _, e := range errs {
		errMsg += e.Translate(trans) + ","
	}
	return errMsg
}



第三步 在初始化路由的时候把翻译器给初始化了

// 初始化路由
func InitRoute() {
	gin.SetMode(utils.AppMode)
	// 初始化路由
	r := gin.Default()
	// 初始化翻译器
	validator.InitValidate()
	r.Use(middleware.InitLogger())
	router := r.Group("/api")

	r.Run(utils.Prot)
}

第四步 使用翻译器

// 验证修改密码
type EditPassRequest struct {
	ID          uint   `json:"id" form:"id" binding:"required,min=0"`
	Password    string `json:"password" form:"password"  binding:"min=6,max=16,alphanum"`
	NewPassword string `json:"newPassword" form:"newPassword"  binding:"max=16,min=6,alphanum"`
}


func EditAdminUserPassword(c *gin.Context) {
	var userPass model.EditPassRequest
	if err := c.ShouldBind(&userPass); err != nil {
		errStr := validator.TranslateValidationError(err)
		msgjson.ErrorMsg(c, errStr)
		return
	}
	if userPass.Password != userPass.NewPassword {
		msgjson.ErrorMsg(c, "两次密码不一致")
		return
	}
	if err := model.EditAdminUserPassword(&userPass); err != nil {
		c.Set("err", "修改密码失败错误信息:"+err.Error())
		msgjson.ServerErrorMsg(c)
		return
	}
	msgjson.SuccessMsg(c, "密码修改成功", nil)
}

image.png