validator库的使用
一、引入
github.com/go-playground/validator
二、使用方式
1、直接在结构体的tag标签中加上binding
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
type SignUpParam struct {
Age uint8 `json:"age" binding:"gte=1,lte=130"`
Name string `json:"name" binding:"required"`
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required"`
RePassword string `json:"re_password" binding:"required,eqfield=Password"`
}
func main() {
r := gin.Default()
r.POST("/signup", func(c *gin.Context) {
var u SignUpParam
if err := c.ShouldBind(&u); err != nil {
c.JSON(http.StatusOK, gin.H{
"msg": err.Error(),
})
return
}
c.JSON(http.StatusOK, "success")
})
_ = r.Run()
}
这样虽然可以实现错误的输出,但是由于全是英文,并不是很友好
2、翻译错误信息
(1)建立中间件的包middleWar,创建validator.go
package middleWar
import (
"fmt"
"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"
enTranslations "github.com/go-playground/validator/v10/translations/en"
zhTranslations "github.com/go-playground/validator/v10/translations/zh"
)
// 定义一个全局翻译器T
var Trans ut.Translator
// InitTrans 初始化翻译器
func InitTrans(locale string) (err error) {
// 修改gin框架中的Validator引擎属性,实现自定制
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
zhT := zh.New() // 中文翻译器
enT := en.New() // 英文翻译器
// 第一个参数是备用(fallback)的语言环境
// 后面的参数是应该支持的语言环境(支持多个)
// uni := ut.New(zhT, zhT) 也是可以的
uni := ut.New(enT, zhT, enT)
// locale 通常取决于 http 请求头的 'Accept-Language'
var ok bool
// 也可以使用 uni.FindTranslator(...) 传入多个locale进行查找
Trans, ok = uni.GetTranslator(locale)
if !ok {
return fmt.Errorf("uni.GetTranslator(%s) failed", locale)
}
// 注册翻译器
switch locale {
case "en":
err = enTranslations.RegisterDefaultTranslations(v, Trans)
case "zh":
err = zhTranslations.RegisterDefaultTranslations(v, Trans)
default:
err = enTranslations.RegisterDefaultTranslations(v, Trans)
}
return
}
return
}
(2)在使用的时候初始化
if err := middleWar.InitTrans("zh"); err != nil {
fmt.Printf("init trans failed, err:%v\n", err)
return
}
(3)参数判断的时候进行类型断言,如果ok就返回翻译错误
if err := c.ShouldBind(&u); err != nil {
errs,ok:=err.(validator.ValidationErrors);
if !ok{
c.JSON(http.StatusOK, gin.H{
"msg": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"msg": errs.Translate(middleWar.Trans),
})
return
}
c.JSON(http.StatusOK, "success")
三、自定义字段名字
由于前端的同学不知道后台的结构体字段,所以需要返回的错误是前端传来的json对象,因此只需要在中间件中假如这个自定义方法
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() // 英文翻译器
}
如果看完对自己有所帮助,请点赞支持,谢谢大家