golang中使用validator进行数据校验及自定义翻译器

您所在的位置:网站首页 ontheplayground翻译中文 golang中使用validator进行数据校验及自定义翻译器

golang中使用validator进行数据校验及自定义翻译器

2024-07-10 18:01| 来源: 网络整理| 查看: 265

目录 一、概述二、使用官方标记符进行数据效验三、自定义标记符和翻译器进行数据效验

一、概述

在接口开发经常需要进行数据校验,validator包是一个比较强大的校验工具包。下面是一些学习总结,全文使用gin框架进行讲解,详细内容可以查看validator

二、使用官方标记符进行数据效验

下面我以“required”进行代码演示,要查看更多标记符可以查看官方文档

导包

import ( "errors" "fmt" "github.com/gin-gonic/gin" "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" enTranslations "github.com/go-playground/validator/v10/translations/en" zhTranslations "github.com/go-playground/validator/v10/translations/zh" "net/http" "reflect" "regexp" "strings" )

定义全局键值对,可以方便取到验证器和翻译器,以及要翻译的语言

const ( ValidatorKey = "ValidatorKey" TranslatorKey = "TranslatorKey" locale = "zh" )

初始化验证器和翻译器

func TransInit(c *gin.Context) { //设置支持语言 chinese := zh.New() english := en.New() //设置国际化翻译器 uni := ut.New(chinese, chinese, english) //设置验证器 val := validator.New() //根据参数取翻译器实例 trans, _ := uni.GetTranslator(locale) //翻译器注册到validator switch locale { case "chinese": zhTranslations.RegisterDefaultTranslations(val, trans) //使用fld.Tag.Get("comment")注册一个获取tag的自定义方法 val.RegisterTagNameFunc(func(fld reflect.StructField) string { return fld.Tag.Get("comment") }) case "english": enTranslations.RegisterDefaultTranslations(val, trans) val.RegisterTagNameFunc(func(fld reflect.StructField) string { return fld.Tag.Get("en_comment") }) } c.Set(TranslatorKey, trans) c.Set(ValidatorKey, val) }

将路由变量params和gin框架绑定

func DefaultGetValidParams(c *gin.Context, params interface{}) error { c.ShouldBind(params) //获取验证器 val, _ := c.Get(ValidatorKey) valid, _ := val.(*validator.Validate) //获取翻译器 tran, _ := c.Get(TranslatorKey) trans, _ := tran.(ut.Translator) err := valid.Struct(params) //如果数据效验不通过,则将所有err以切片形式输出 if err != nil { errs := err.(validator.ValidationErrors) sliceErrs := []string{} for _, e := range errs { //使用validator.ValidationErrors类型里的Translate方法进行翻译 sliceErrs = append(sliceErrs, e.Translate(trans)) } return errors.New(strings.Join(sliceErrs, ",")) } return nil }

接下来我们定义一个结构体,对其传参检验输出结果 form是前端传入的参数名;comment是自定义tag,本文表示的是参数报错时显示的名称;validate里传入标记符,这里传入’required’(字段必填)

type login struct { Username string ` form:"username" comment:"用户名" validate:"required"` }

编写路由函数

func loginTest(c *gin.Context) { TransInit(c) req:=&login{} err:=DefaultGetValidParams(c,req) //失败时输出 if err != nil { c.JSON(404, gin.H{ "code": 2000, "err": err.Error(), }) return } //成功时输出 c.JSON(http.StatusOK, gin.H{ "code": 0, "msg": "success", "name":req.Username, }) }

最后运行

func main() { route := gin.Default() route.POST("/login",loginTest) route.Run(":8099") }

使用Postman进行测试: 在这里插入图片描述 如果没填参数则提示“必填”: 在这里插入图片描述 如果把翻译的语言改为英语,效验失败时如下输出:

const ( ValidatorKey = "ValidatorKey" TranslatorKey = "TranslatorKey" //locale = "chinese" locale = "english" )

在这里插入图片描述

三、自定义标记符和翻译器进行数据效验

相比于官方定义好可以直接拿来用的标记符,自定义标记符具有更广泛的应用,我在项目中经常用的也是自定义标记符。同时自定义翻译器也可以更清楚的告诉用户格式输入错误。 首先自定义一个标识符"valid_username"

type login struct { Username string ` form:"username" comment:"用户名" validate:"required,valid_username"` }

这里我使用了正则进行效验。更多的正则匹配规则可自行百度,这里不作更多介绍 在初始化翻译器中加入如下函数:

//自定义验证方法 val.RegisterValidation("valid_username", func(fl validator.FieldLevel) bool { matched, _ := regexp.Match("^[a-z]{6,30}$", []byte(fl.Field().String())) return matched }) //自定义翻译器 val.RegisterTranslation("valid_username", trans, func(ut ut.Translator) error { return ut.Add("valid_username", "{0}输入格式不正确或长度不符", true) }, func(ut ut.Translator, fe validator.FieldError) string { t, _ := ut.T("valid_username", fe.Field()) return t })

即:

func TransInit(c *gin.Context) { //设置支持语言 chinese := zh.New() english := en.New() //设置国际化翻译器 uni := ut.New(chinese, chinese, english) //设置验证器 val := validator.New() //根据参数取翻译器实例 trans, _ := uni.GetTranslator(locale) //翻译器注册到validator switch locale { case "chinese": zhTranslations.RegisterDefaultTranslations(val, trans) val.RegisterTagNameFunc(func(fld reflect.StructField) string { return fld.Tag.Get("comment") }) //自定义验证方法 val.RegisterValidation("valid_username", func(fl validator.FieldLevel) bool { matched, _ := regexp.Match("^[a-z]{6,30}$", []byte(fl.Field().String())) return matched }) //自定义翻译器 val.RegisterTranslation("valid_username", trans, func(ut ut.Translator) error { return ut.Add("valid_username", "{0}输入格式不正确或长度不符", true) }, func(ut ut.Translator, fe validator.FieldError) string { t, _ := ut.T("valid_username", fe.Field()) return t }) case "english": enTranslations.RegisterDefaultTranslations(val, trans) //使用fld.Tag.Get("en_comment")注册一个获取tag的自定义方法 val.RegisterTagNameFunc(func(fld reflect.StructField) string { return fld.Tag.Get("en_comment") }) } c.Set(TranslatorKey, trans) c.Set(ValidatorKey, val) }

重新运行查看结果 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3