Gin框架的数据校验
2024-01-08 16:42:10
抛出问题:
使用默认的数据校验,校验失败时,返回的提示信息为英文,且根据提示信息没法判断校验失败的原因,体验感很差。
解决:
自定义校验,注册翻译器
涉及的包:
en2 "github.com/go-playground/locales/en"
zh2 "github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
en_translations "github.com/go-playground/validator/v10/translations/en"
zh_translations "github.com/go-playground/validator/v10/translations/zh"
结构体在校验时不在使用binding,使用validate。
var query struct {
Name string `form:"name" json:"name,omitempty" validate:"omitempty,max=128"`
Id int `form:"id" json:"id,omitempty" validate:"omitempty,numeric,gte=1"`
PerShopId string `form:"per_shop_id" json:"per_shop_id,omitempty"`
PerCategory string `form:"per_category" json:"per_category,omitempty"`
PerErpArea string `form:"per_erp_area" json:"per_erp_area,omitempty"`
Page int `form:"page" json:"page" validate:"required,gte=1"`
PageSize int `form:"page_size" json:"page_size" validate:"required,gte=1"`
}
构建语言转换器及注册:
- 将Validate做成一个单例。手动定义了一个ErrorOnce(仿照标准库的sync.Once),目的在于初始化函数失败后,后续可以继续初始化该单例
- GetValidate():通过该函数获取校验器。其中创建了validate,并为其注册了中文翻译器
- GetErrInfo():用于获取校验结果,如果有错误,会以Map和切片的结构返回校验错误信息,根据需求确定
import (
"fmt"
"github.com/gin-gonic/gin"
lzh "github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
translations "github.com/go-playground/validator/v10/translations/zh"
"strings"
"sync"
"sync/atomic"
)
var (
uni *ut.UniversalTranslator
validate *validator.Validate
validateOnce = &ErrorOnce{}
trans ut.Translator
)
type ErrorOnce struct {
m sync.Mutex
done uint32
}
func (v *ErrorOnce) Do(f func() error) error {
if atomic.LoadUint32(&v.done) == 1 {
return nil
}
return v.doSlow(f)
}
func (v *ErrorOnce) doSlow(f func() error) error {
v.m.Lock()
defer v.m.Unlock()
var err error
if v.done == 0 {
err = f()
if err == nil {
atomic.StoreUint32(&v.done, 1)
}
}
return err
}
func GetValidate() *validator.Validate {
err := validateOnce.Do(func() error {
zh := lzh.New()
uni = ut.New(zh)
validate = validator.New()
trans, _ = uni.GetTranslator("zh")
return translations.RegisterDefaultTranslations(validate, trans)
})
fmt.Println("GetValidate-err->", err)
return validate
}
func GetErrInfo(err error) (map[string]string, []string) {
errs := err.(validator.ValidationErrors)
sliceErrs := make([]string, len(errs))
for i, e := range errs {
sliceErrs[i] = e.Translate(trans)
}
return errs.Translate(trans), sliceErrs
}
使用:
- 进行参数绑定
- 获取校验器校验参数,并获取error
err := c.ShouldBindQuery(&query)
if err != nil {
c.JSON(http.StatusBadRequest, info)
return
}
//参数校验
if err = GetValidate().Struct(query); err != nil {
info, _ := GetErrInfo(err)
c.JSON(http.StatusBadRequest, info)
return
}
文章来源:https://blog.csdn.net/q79030/article/details/135459229
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!