介绍

Validator 是基于 tag(标记)实现结构体和单个字段的值验证库,它包含以下功能:

  • 使用验证 tag(标记)或自定义验证器进行跨字段和跨结构体验证。
  • 关于 slice、数组和 map,允许验证多维字段的任何或所有级别。
  • 能够深入 map 键和值进行验证。
  • 通过在验证之前确定接口的基础类型来处理类型接口。
  • 处理自定义字段类型(如 sql 驱动程序 Valuer)。
  • 别名验证标记,它允许将多个验证映射到单个标记,以便更轻松地定义结构体上的验证。
  • 提取自定义的字段名称,例如,可以指定在验证时提取 JSON 名称,并在生成的 FieldError 中使用该名称。
  • 可自定义 i18n 错误消息。
  • Web 框架 gin 的默认验证器。

安装:

使用 go get:

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

然后将 Validator 包导入到代码中:

import "github.com/go-playground/validator/v10"

变量验证

Var 方法使用 tag(标记)验证方式验证单个变量。

func (*validator.Validate).Var(field interface{}, tag string) error

它接收一个 interface{} 空接口类型的 field 和一个 string 类型的 tag,返回传递的非法值得无效验证错误,否则将 nil 或 ValidationErrors 作为错误。如果错误不是 nil,则需要断言错误去访问错误数组,例如:

validationErrors := err.(validator.ValidationErrors)

如果是验证数组、slice 和 map,可能会包含多个错误。

示例代码:

func main() {
  validate := validator.New()
  // 验证变量
  email := "admin#admin.com"
  email := ""
  err := validate.Var(email, "required,email")
  if err != nil {
    validationErrors := err.(validator.ValidationErrors)
    fmt.Println(validationErrors)
    // output: Key: '' Error:Field validation for '' failed on the 'email' tag
    // output: Key: '' Error:Field validation for '' failed on the 'required' tag
    return
  }
}

结构体验证

结构体验证结构体公开的字段,并自动验证嵌套结构体,除非另有说明。

func (*validator.Validate).Struct(s interface{}) error

它接收一个 interface{} 空接口类型的 s,返回传递的非法值得无效验证错误,否则将 nil 或 ValidationErrors 作为错误。如果错误不是 nil,则需要断言错误去访问错误数组,例如:

validationErrors := err.(validator.ValidationErrors)

实际上,Struct 方法是调用的 StructCtx 方法,因为本文不是源码讲解,所以此处不展开赘述,如有兴趣,可以查看源码。

示例代码:

func main() {
  validate = validator.New()
  type User struct {
    ID     int64  `json:"id" validate:"gt=0"`
    Name   string `json:"name" validate:"required"`
    Gender string `json:"gender" validate:"required,oneof=man woman"`
    Age    uint8  `json:"age" validate:"required,gte=0,lte=130"`
    Email  string `json:"email" validate:"required,email"`
  }
  user := &User{
    ID:     1,
    Name:   "frank",
    Gender: "boy",
    Age:    180,
    Email:  "gopher@88.com",
  }
  err = validate.Struct(user)
  if err != nil {
    validationErrors := err.(validator.ValidationErrors)
    // output: Key: 'User.Age' Error:Field validation for 'Age' failed on the 'lte' tag
    // fmt.Println(validationErrors)
    fmt.Println(validationErrors.Translate(trans))
    return
  }
}

细心的读者可能已经发现,错误输出信息并不友好,错误输出信息中的字段不仅没有使用备用名(首字母小写的字段名),也没有翻译为中文。通过改动代码,使错误输出信息变得友好。

注册一个函数,获取结构体字段的备用名称:

validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
    name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
    if name == "-" {
      return "j"
    }
    return name
  })

错误信息翻译为中文:

zh := zh.New()
uni = ut.New(zh)
trans, _ := uni.GetTranslator("zh")
_ = zh_translations.RegisterDefaultTranslations(validate, trans)

标签

通过以上章节的内容,读者应该已经了解到 Validator 是一个基于 tag(标签),实现结构体和单个字段的值验证库。

本章节列举一些比较常用的标签:

标签 描述
eq 等于
gt 大于
gte 大于等于
lt 小于
lte 小于等于
ne 不等于
max 最大值
min 最小值
oneof 其中一个
required 必需的
unique 唯一的
isDefault 默认值
len 长度
email 邮箱格式

转自: Golang语言开发栈

最后编辑: kuteng  文档更新时间: 2020-12-28 19:17   作者:kuteng