golang通过标签自动验证结构体字段插件库validate的使用

Golang通过标签自动验证结构体字段插件库validate的使用

简介

Validate是一个Go语言的包,用于通过标签自动验证结构体字段。它提供了一种简单的方式来验证结构体字段是否符合预期要求。

安装

使用go get命令安装validate包:

go get github.com/mccoyst/validate

基本使用示例

下面是一个使用validate包的基本示例:

package main

import (
	"fmt"
	"github.com/mccoyst/validate"
)

// 定义一个用户结构体,添加validate标签
type User struct {
	Username string `validate:"min=4,max=20"`  // 用户名长度在4-20之间
	Email    string `validate:"email"`         // 必须是有效的电子邮件格式
	Age      int    `validate:"min=18,max=99"` // 年龄必须在18-99之间
}

func main() {
	// 创建一个验证器实例
	v := validate.New()

	// 创建一个测试用户
	user := User{
		Username: "john",  // 有效
		Email:    "john@example.com",  // 有效
		Age:      17,  // 无效,小于18
	}

	// 验证结构体
	if err := v.Validate(user); err != nil {
		// 打印验证错误
		fmt.Println("验证失败:", err)
	} else {
		fmt.Println("验证通过")
	}
}

支持的验证规则

validate库支持多种验证规则,下面是一些常用规则的示例:

type Product struct {
	ID       string `validate:"required"`    // 必填字段
	Name     string `validate:"min=3,max=50"`  // 长度3-50
	Price    float64 `validate:"min=0.01"`   // 最小值为0.01
	Quantity int     `validate:"min=1"`      // 最小值为1
	Category string `validate:"oneof=electronics clothing furniture"`  // 只能是列举的值之一
	Code     string `validate:"regexp=^[A-Z]{3}[0-9]{3}$"`  // 必须匹配正则表达式
}

自定义验证函数

你还可以定义自己的验证函数:

package main

import (
	"fmt"
	"github.com/mccoyst/validate"
)

// 自定义验证函数 - 检查是否是偶数
func isEven(v interface{}) error {
	i, ok := v.(int)
	if !ok {
		return fmt.Errorf("必须是整数")
	}
	if i%2 != 0 {
		return fmt.Errorf("必须是偶数")
	}
	return nil
}

func main() {
	v := validate.New()
	
	// 注册自定义验证函数
	v.RegisterValidator("even", isEven)
	
	// 使用自定义验证
	type Data struct {
		Number int `validate:"even"`
	}
	
	data := Data{Number: 3}
	if err := v.Validate(data); err != nil {
		fmt.Println("验证失败:", err) // 会输出"必须是偶数"
	}
}

嵌套结构验证

validate也支持嵌套结构体的验证:

type Address struct {
	Street string `validate:"required"`
	City   string `validate:"required"`
	Zip    string `validate:"len=5"`
}

type Person struct {
	Name    string  `validate:"required"`
	Age     int     `validate:"min=18"`
	Address Address `validate:"required"`
}

func main() {
	v := validate.New()
	
	person := Person{
		Name: "Alice",
		Age:  20,
		Address: Address{
			Street: "123 Main St",
			City:   "New York",
			Zip:    "1000",  // 无效,长度应为5
		},
	}
	
	if err := v.Validate(person); err != nil {
		fmt.Println("验证失败:", err) // 会输出Zip长度错误
	}
}

结论

validate包提供了一种简单而强大的方式来验证Go结构体字段。通过使用结构体标签,你可以轻松地为字段添加验证规则,而无需编写大量重复的验证代码。它支持内置验证规则,也允许自定义验证函数,非常适合在Web应用或API开发中使用。


更多关于golang通过标签自动验证结构体字段插件库validate的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang通过标签自动验证结构体字段插件库validate的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 结构体字段验证库 validate 使用指南

在 Go 语言中,validate 是一个流行的结构体字段验证库,它通过结构体标签来定义验证规则。下面我将详细介绍如何使用这个库。

安装

首先安装 validate 库:

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

基本用法

package main

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

// User 结构体定义验证规则
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"`                // 必须是有效的颜色
	Addresses      []*Address `validate:"required,dive,required"` // dive 表示深入验证切片中的每个元素
}

// Address 子结构体
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, // 不符合 lte=130 规则
		Email:          "Badger.Smith@gmail.com",
		FavouriteColor: "#000-",
		Addresses: []*Address{
			{Street: "Eavesdown Docks", City: "Beijing", Planet: "Earth", Phone: "none"},
			{Street: "", City: "Beijing", Planet: "Earth", Phone: "none"}, // 缺少 Street
		},
	}

	// 执行验证
	err := validate.Struct(user)
	if err != nil {
		// 处理验证错误
		for _, err := range err.(validator.ValidationErrors) {
			fmt.Printf("字段 %s 验证失败: 标签 %s 的值 '%v' 不满足条件\n", 
				err.Field(), err.Tag(), err.Value())
		}
		return
	}
	
	fmt.Println("验证通过")
}

常用验证标签

validate 提供了丰富的验证标签:

  • 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
  • uuid - 必须是有效的UUID
  • uuid3 - 必须是有效的v3 UUID
  • uuid4 - 必须是有效的v4 UUID
  • uuid5 - 必须是有效的v5 UUID
  • datetime=2006-01-02 - 必须匹配给定的日期时间格式
  • timezone - 必须是有效的时区名称
  • ip - 必须是有效的IP地址
  • ipv4 - 必须是有效的IPv4地址
  • ipv6 - 必须是有效的IPv6地址
  • mac - 必须是有效的MAC地址

自定义验证规则

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

package main

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

// 自定义验证函数
func validateCool(fl validator.FieldLevel) bool {
	return fl.Field().String() == "cool"
}

func main() {
	validate := validator.New()
	
	// 注册自定义验证函数
	_ = validate.RegisterValidation("cool", validateCool)

	type User struct {
		Name string `validate:"required,cool"`
	}

	user := User{Name: "hot"}
	err := validate.Struct(user)
	if err != nil {
		for _, err := range err.(validator.ValidationErrors) {
			fmt.Printf("字段 %s 验证失败: 标签 %s 的值 '%v' 不满足条件\n", 
				err.Field(), err.Tag(), err.Value())
		}
		return
	}
	
	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",
	}
	
	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"
)

type User struct {
	Name string `validate:"required"`
	Age  int    `validate:"min=18"`
}

var validate *validator.Validate

func init() {
	validate = validator.New()
}

func main() {
	user := User{Name: "John", Age: 20}
	if err := validate.Struct(user); err != nil {
		fmt.Println(err)
	}
}

总结

validate 库提供了强大而灵活的结构体验证功能,通过结构体标签可以轻松定义验证规则,支持丰富的内置验证器和自定义验证器,还能实现错误消息的国际化。它是 Go 语言中最流行的验证库之一,适合各种规模的应用程序。

回到顶部