validator库参数校验
web开发中,我们不可避免的对一些参数进行各种校验,比如长度限定,类型限定等等,以前做Java的时候,自己直接 if else就应付了,写的老长老长了,这显然不合理。
- gin框架使用github.com/go-playground/validator进行参数校验
- 并且支持github.com/go-playground/validator/v10,我们需要在定义结构体时使用 binding tag标识相关校验规则。
可以的话,最好也去看看 官方文档 啦
binding属性
字符串约束
名称 | 含义 |
---|---|
excludesall | 不包含参数中任意的 UNICODE 字符,例如excludesall=ab; |
excludesrune | 不包含参数表示的 rune 字符,excludesrune=asong; |
startswith | 以参数子串为前缀,例如startswith=hi; |
endswith | 以参数子串为后缀,例如endswith=bye。 |
contains | 包含参数子串,例如contains=email; |
containsany | 包含参数中任意的 UNICODE 字符,例如containsany=ab; |
containsrune | 包含参数表示的 rune 字符,例如`containsrune=asong; |
excludes | 不包含参数子串,例如excludes=email; |
范围约束
名称 | 含义 |
---|---|
ne | 不等于参数值,例如 ne=5; |
gt | 大于参数值,例如 gt=5; |
gte | 大于等于参数值,例如 gte=50; |
lt | 小于参数值,例如 lt=50; |
lte | 小于等于参数值,例如 lte=50; |
oneof | 只能是列举出的值其中一个,这些值必须是数值或字符串,以空格分隔,如果字符串中有空格,将字符串用单引号包围,例如 oneof=male female。 |
eq | 等于参数值,注意与 len不同。对于字符串, eq约束字符串本身的值,而 len约束字符串长度。例如 eq=10; |
len | 等于参数值,例如 len=10; |
max | 小于等于参数值,例如 max=10; |
min | 大于等于参数值,例如 min=10; |
结构体属性约束
名称 | 含义 |
---|---|
eqfield | 定义字段间的相等约束,用于约束同一结构体中的字段。例如: eqfield=Password |
eqcsfield | 约束统一结构体中字段等于另一个字段(相对),确认密码时可以使用,例如: eqfiel=ConfirmPassword |
nefield | 用来约束两个字段是否相同,确认两种颜色是否一致时可以使用,例如: nefield=Color1 |
necsfield | 约束两个字段是否相同(相对) |
其余常用约束
名称 | 含义 |
---|---|
unique | 指定唯一性约束,不同类型处理不同: |
使用email来限制字段必须是邮件形式,直接写eamil即可,无需加任何指定。 | |
omitempty | 字段未设置,则忽略 |
- | 跳过该字段,不检验; |
| | 使用多个约束,只需要满足其中一个,例如a |
required | 字段必须设置,不能为默认值; |
- 这些应该够用来,嗯嗯
翻译器
validator校验出来后的error直接返回的话,显示的是英文,为了方便我们可以做个翻译器
package utils
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"
"reflect"
"strings"
)
// Trans 定义一个全局翻译器T
var Trans ut.Translator
// InitTrans 初始化翻译器
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() // 英文翻译器
// 第一个参数是备用(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
}
// RemoveTopStruct 去除结构体上面前面的信息,保留后面的主要部分,例如: ParamsSignUp.re_password -> re_password
func RemoveTopStruct(fields map[string]string) map[string]string {
res := map[string]string{}
for field, err := range fields {
res[field[strings.Index(field, ".")+1:]] = err
}
return res
}
- 好用!