golang应用程序数据验证框架插件库validate的使用

golang应用程序数据验证框架插件库validate的使用

安装

$ go get github.com/gobuffalo/validate

基本用法

这个包为Go应用程序提供了一个验证框架。它确实提供了一些验证器,但如果你需要其他验证器,可以轻松构建它们。

简单示例

package main

import (
	"log"

	v "github.com/gobuffalo/validate"
)

type User struct {
	Name  string
	Email string
}

// 为User结构体实现IsValid方法
func (u *User) IsValid(errors *v.Errors) {
	if u.Name == "" {
		errors.Add("name", "Name must not be blank!")
	}
	if u.Email == "" {
		errors.Add("email", "Email must not be blank!")
	}
}

func main() {
	u := User{Name: "", Email: ""}
	errors := v.Validate(&u)
	log.Println(errors.Errors)
	// 输出: map[name:[Name must not be blank!] email:[Email must not be blank!]]
}

更灵活的验证器示例

package main

import (
	"fmt"
	"log"
	"strings"

	v "github.com/gobuffalo/validate"
)

type User struct {
	Name  string
	Email string
}

// 自定义PresenceValidator验证器
type PresenceValidator struct {
	Field string
	Value string
}

func (v *PresenceValidator) IsValid(errors *v.Errors) {
	if v.Value == "" {
		errors.Add(strings.ToLower(v.Field), fmt.Sprintf("%s must not be blank!", v.Field))
	}
}

func main() {
	u := User{Name: "", Email: ""}
	errors := v.Validate(
		&PresenceValidator{"Email", u.Email}, 
		&PresenceValidator{"Name", u.Name},
	)
	log.Println(errors.Errors)
	// 输出: map[name:[Name must not be blank!] email:[Email must not be blank!]]
}

内置验证器

为了更简单,这个包还有一个子包,提供了一些内置的验证器。

package main

import (
	"log"

	"github.com/gobuffalo/validate"
	"github.com/gobuffalo/validate/validators"
)

type User struct {
	Name  string
	Email string
}

func main() {
	u := User{Name: "", Email: ""}
	errors := validate.Validate(
		&validators.EmailIsPresent{
			Name:    "Email", 
			Field:   u.Email, 
			Message: "Mail is not in the right format.",
		},
		&validators.StringIsPresent{
			Field: u.Name, 
			Name:  "Name",
		},
	)
	log.Println(errors.Errors)
	// 输出: map[name:[Name can not be blank.] email:[Mail is not in the right format.]]
}

所有验证器的字段都是必需的,除了Message(每个验证器都有默认的错误消息)。

可用验证器

完整的可用验证器列表可以在官方文档中找到。


更多关于golang应用程序数据验证框架插件库validate的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang应用程序数据验证框架插件库validate的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 数据验证框架 validate 使用指南

validate 是 Go 语言中一个流行的数据验证库,它提供了结构体标签的方式来定义验证规则。下面我将详细介绍如何使用这个库。

安装

首先安装 validate 库:

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

基本用法

package main

import (
	"fmt"
	"github.com/go-playground/validator/v10"
)

type User struct {
	FirstName      string     `validate:"required"`
	LastName       string     `validate:"required"`
	Age            uint8      `validate:"gte=0,lte=130"`
	Email          string     `validate:"required,email"`
	FavouriteColor string     `validate:"iscolor"`                // alias for 'hexcolor|rgb|rgba|hsl|hsla'
	Addresses      []*Address `validate:"required,dive,required"` // dive 表示深入验证嵌套结构
}

type Address struct {
	Street string `validate:"required"`
	City   string `validate:"required"`
	Planet string `validate:"required"`
	Phone  string `validate:"required"`
}

func main() {
	validate := validator.New()

	user := &User{
		FirstName:      "Badger",
		LastName:       "Smith",
		Age:            135,
		Email:          "Badger.Smith@gmail.com",
		FavouriteColor: "#000-",
		Addresses: []*Address{
			{
				Street: "Eavesdown Docks",
				Planet: "Persphone",
				Phone:  "none",
			},
		},
	}

	err := validate.Struct(user)
	if err != nil {
		for _, err := range err.(validator.ValidationErrors) {
			fmt.Println(err.Namespace()) // 字段全路径
			fmt.Println(err.Field())     // 字段名
			fmt.Println(err.StructNamespace())
			fmt.Println(err.StructField())
			fmt.Println(err.Tag())       // 验证标签
			fmt.Println(err.ActualTag())// 实际使用的验证标签
			fmt.Println(err.Kind())      // 字段类型
			fmt.Println(err.Type())     // 字段类型
			fmt.Println(err.Value())     // 字段值
			fmt.Println(err.Param())     // 验证参数
			fmt.Println()
		}
	}
}

常用验证标签

标签 说明
required 必填字段
omitempty 如果字段为空则跳过验证
len=10 长度等于10
min=1 最小值1
max=10 最大值10
eq=10 等于10
ne=10 不等于10
gt=10 大于10
gte=10 大于等于10
lt=10 小于10
lte=10 小于等于10
eqfield=Field 等于另一个字段的值
nefield=Field 不等于另一个字段的值
alpha 仅包含字母字符
alphanum 仅包含字母和数字字符
numeric 仅包含数字字符
hexadecimal 有效的十六进制字符串
hexcolor 有效的十六进制颜色代码
rgb 有效的RGB颜色
rgba 有效的RGBA颜色
hsl 有效的HSL颜色
hsla 有效的HSLA颜色
email 有效的电子邮件地址
url 有效的URL
uri 有效的URI
base64 有效的Base64字符串
contains=@ 包含子字符串"@"
excludes=@ 不包含子字符串"@"
startswith=prefix 以"prefix"开头
endswith=suffix 以"suffix"结尾
ip 有效的IP地址
ipv4 有效的IPv4地址
ipv6 有效的IPv6地址
uuid 有效的UUID
uuid3 有效的UUID v3
uuid4 有效的UUID v4
uuid5 有效的UUID v5
datetime=2006-01-02 符合指定格式的日期时间
json 有效的JSON字符串
number 有效的数字
numeric 有效的数字或数字字符串
lowercase 全小写字符
uppercase 全大写字符

自定义验证

可以注册自定义验证函数:

package main

import (
	"fmt"
	"github.com/go-playground/validator/v10"
)

// 自定义验证函数
func validateVATNumber(fl validator.FieldLevel) bool {
	vatNumber := fl.Field().String()
	// 这里实现你的验证逻辑
	return len(vatNumber) == 10
}

type Invoice struct {
	VATNumber string `validate:"vatnumber"`
}

func main() {
	validate := validator.New()
	
	// 注册自定义验证函数
	err := validate.RegisterValidation("vatnumber", validateVATNumber)
	if err != nil {
		panic(err)
	}

	invoice := &Invoice{
		VATNumber: "1234567890",
	}

	err = validate.Struct(invoice)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("验证通过")
	}
}

国际化错误消息

validate 支持错误消息的国际化:

package main

import (
	"fmt"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	zh_translations "github.com/go-playground/validator/v10/translations/zh"
)

type User struct {
	Username string `validate:"required"`
	Email    string `validate:"required,email"`
}

func main() {
	// 中文翻译器
	zh_ch := zh.New()
	uni := ut.New(zh_ch, zh_ch)
	trans, _ := uni.GetTranslator("zh")
	
	validate := validator.New()
	// 注册中文翻译
	zh_translations.RegisterDefaultTranslations(validate, trans)
	
	user := User{
		Username: "",
		Email:    "invalid_email",
	}
	
	err := validate.Struct(user)
	if err != nil {
		errs := err.(validator.ValidationErrors)
		for _, e := range errs {
			// 翻译错误信息
			fmt.Println(e.Translate(trans))
		}
	}
}

验证单个值

除了验证结构体,也可以验证单个值:

package main

import (
	"fmt"
	"github.com/go-playground/validator/v10"
)

func main() {
	validate := validator.New()
	
	// 验证单个字符串
	err := validate.Var("example@gmail.com", "required,email")
	if err != nil {
		fmt.Println(err)
	}
	
	// 验证数字范围
	err = validate.Var(15, "gte=10,lte=20")
	if err != nil {
		fmt.Println(err)
	}
}

性能考虑

validate 库在性能上做了很多优化,但在高频场景下仍有一些建议:

  1. 重用 validator 实例(它是并发安全的)
  2. 避免在热路径上频繁创建 validator 实例
  3. 对于简单验证,可以考虑直接使用标准库函数

validate 是一个功能强大且灵活的数据验证库,适合大多数 Go 应用程序的数据验证需求。

回到顶部