validator

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 24, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package validator 提供数据验证功能,封装 go-playground/validator/v10。

validator 包提供结构体标签验证、自定义验证规则和中文错误消息支持。 基于 go-playground/validator/v10,提供更简洁的 API 和开箱即用的中文支持。

功能特性

  • 结构体标签验证
  • 自定义验证规则
  • 中文错误消息
  • label 字段名标签支持
  • 中国大陆手机号、身份证号、银行卡号验证
  • 并发安全

快速开始

type User struct {
	Name  string `validate:"required" label:"姓名"`
	Email string `validate:"required,email" label:"邮箱"`
	Age   int    `validate:"min=18,max=100" label:"年龄"`
}

user := User{
	Name:  "张三",
	Email: "zhangsan@example.com",
	Age:   25,
}

if err := validator.Validate(user); err != nil {
	log.Fatal(err)
}

字段名标签

type User struct {
	Name  string `validate:"required" label:"姓名"`
	Email string `validate:"required,email" label:"邮箱"`
	Age   int    `validate:"min=18,max=100" label:"年龄"`
}

// 错误消息会显示:姓名为必填字段

创建自定义验证器

v := validator.New()

// 注册自定义验证规则
v.RegisterValidation("username", func(fl validator.FieldLevel) bool {
	username := fl.Field().String()
	// 用户名只能包含字母、数字和下划线
	return regexp.MustCompile(`^[a-zA-Z0-9_]+$`).MatchString(username)
})

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

自定义字段名标签

v := validator.New(validator.WithFieldNameTag("json"))

type User struct {
	Name string `json:"name" validate:"required"`
}

内置中国本地化规则

type User struct {
	Phone    string `validate:"phone" label:"手机号"`
	IDCard   string `validate:"id_card" label:"身份证号"`
	BankCard string `validate:"bank_card" label:"银行卡号"`
}

条件验证

type User struct {
	Role     string `validate:"required,oneof=admin user guest"`
	Password string `validate:"required_if=Role admin,min=8"`
}

// 如果 Role 是 admin,则 Password 必填且至少 8 位

常用验证标签

## 必填验证

required              // 必填
required_if=Field Val // 如果 Field 等于 Val,则必填
required_unless       // 除非...否则必填
required_with         // 如果其他字段存在,则必填
required_without      // 如果其他字段不存在,则必填

## 字符串验证

min=10                // 最小长度
max=100               // 最大长度
len=20                // 固定长度
email                 // 邮箱格式
url                   // URL 格式
alpha                 // 只包含字母
alphanum              // 只包含字母和数字
numeric               // 只包含数字

## 数字验证

min=18                // 最小值
max=100               // 最大值
gt=0                  // 大于
gte=0                 // 大于等于
lt=100                // 小于
lte=100               // 小于等于
eq=10                 // 等于
ne=0                  // 不等于
oneof=1 2 3           // 枚举值

## 日期验证

datetime=2006-01-02   // 日期格式

## 比较验证

eqfield=Password      // 等于另一个字段
nefield=OldPassword   // 不等于另一个字段
gtfield=StartDate     // 大于另一个字段
ltfield=EndDate       // 小于另一个字段

## 切片/数组验证

min=1                 // 最小元素数
max=10                // 最大元素数
unique                // 元素唯一
dive                  // 验证切片中的每个元素

复杂验证示例

## 嵌套结构体

type Address struct {
	City    string `validate:"required" label:"城市"`
	Street  string `validate:"required" label:"街道"`
	ZipCode string `validate:"required,len=6" label:"邮编"`
}

type User struct {
	Name    string  `validate:"required" label:"姓名"`
	Address Address `validate:"required,dive"`
}

## 切片验证

type User struct {
	Tags []string `validate:"required,min=1,max=5,dive,min=2,max=20"`
}

// Tags 必填,至少 1 个,最多 5 个
// 每个 tag 长度在 2-20 之间

自定义错误消息

v := validator.New()

v.RegisterTranslation("username", "{0}只能包含字母、数字和下划线")

最佳实践

## 1. 使用默认验证器

// 推荐:使用包级函数
err := validator.Validate(user)

// 不推荐:每次创建新验证器
v := validator.New()
err := v.Validate(user)

## 2. 使用 label 标签自定义字段名

type User struct {
	Name string `validate:"required" label:"用户名"`
}

// 错误消息:用户名为必填字段

## 3. 组合验证规则

type User struct {
	Email string `validate:"required,email,max=100"`
}

## 4. 在 HTTP 处理器中使用

func CreateUser(c *gin.Context) {
	var user User
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	if err := validator.Validate(user); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	// 创建用户
}

## 5. 验证请求参数

type CreateUserRequest struct {
	Username string `json:"username" validate:"required,min=3,max=20"`
	Email    string `json:"email" validate:"required,email"`
	Password string `json:"password" validate:"required,min=8"`
	Age      int    `json:"age" validate:"required,min=18,max=100"`
}

错误处理

err := validator.Validate(user)
if err != nil {
	fmt.Println(err.Error())
}

性能考虑

  • 验证器实例是线程安全的,应该复用
  • 使用默认验证器避免重复初始化
  • 验证规则会被缓存,重复验证性能很好

线程安全

所有验证器实例都是线程安全的,可以在多个 goroutine 中并发使用。

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func RegisterTranslation

func RegisterTranslation(tag, message string) error

RegisterTranslation 在默认验证器上注册自定义翻译消息。

这是一个便捷函数,内部使用全局默认验证器实例。

示例:

validator.RegisterTranslation("phone", "手机号格式不正确")

func RegisterValidation

func RegisterValidation(tag string, fn validator.Func) error

RegisterValidation 在默认验证器上注册自定义验证规则。

这是一个便捷函数,内部使用全局默认验证器实例。

示例:

validator.RegisterValidation("phone", func(fl validator.FieldLevel) bool {
    phone := fl.Field().String()
    return len(phone) == 11
})
Example

ExampleRegisterValidation 演示全局注册自定义验证规则

package main

import (
	"fmt"

	"github.com/f2xme/gox/validator"
	validatorv10 "github.com/go-playground/validator/v10"
)

func main() {
	type User struct {
		Username string `validate:"username_rule"`
	}

	// 全局注册自定义规则:用户名必须以字母开头
	validator.RegisterValidation("username_rule", func(fl validatorv10.FieldLevel) bool {
		username := fl.Field().String()
		if len(username) == 0 {
			return false
		}
		first := username[0]
		return (first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z')
	})

	user := User{Username: "alice"}
	if err := validator.Validate(user); err != nil {
		fmt.Println("验证失败:", err)
	} else {
		fmt.Println("用户名验证成功")
	}

}
Output:
用户名验证成功

func Validate

func Validate(i any) error

Validate 使用默认验证器验证结构体。

这是一个便捷函数,内部使用全局默认验证器实例。 默认验证器是并发安全的。

示例:

type User struct {
    Name string `validate:"required"`
}
user := User{Name: "张三"}
if err := validator.Validate(user); err != nil {
    log.Fatal(err)
}
Example

ExampleValidate 演示基本验证用法

package main

import (
	"fmt"

	"github.com/f2xme/gox/validator"
)

func main() {
	type User struct {
		Name  string `validate:"required"`
		Email string `validate:"email"`
		Age   int    `validate:"min=18,max=100"`
	}

	// 验证成功的例子
	user := User{
		Name:  "张三",
		Email: "zhangsan@example.com",
		Age:   25,
	}

	if err := validator.Validate(user); err != nil {
		fmt.Println("验证失败:", err)
	} else {
		fmt.Println("验证成功")
	}

}
Output:
验证成功

Types

type Option added in v0.2.0

type Option func(*Options)

Option 定义验证器配置选项函数。

func WithFieldNameTag added in v0.2.0

func WithFieldNameTag(tag string) Option

WithFieldNameTag 设置错误消息中使用的字段名标签。

传入空字符串时,错误消息使用结构体字段名。

示例:

v := validator.New(validator.WithFieldNameTag("json"))

type Options added in v0.2.0

type Options struct {
	// FieldNameTag 指定用于错误消息字段名的结构体标签,默认使用 label。
	FieldNameTag string
}

Options 定义验证器配置选项。

type Validator

type Validator struct {
	// contains filtered or unexported fields
}

Validator 封装 go-playground/validator 实例,提供数据验证功能。 实例是并发安全的,可以在多个 goroutine 中共享使用。

func Default added in v0.3.0

func Default() *Validator

Default 返回全局默认验证器实例。

默认验证器使用懒加载初始化,并且可以安全地在多个 goroutine 中共享。

示例:

v := validator.Default()
err := v.Validate(user)

func New

func New(opts ...Option) *Validator

New 创建一个新的验证器实例,默认支持中文错误消息和中国本地化验证规则。

返回的验证器实例是并发安全的,可以在多个 goroutine 中共享使用。

示例:

v := validator.New()
err := v.Validate(user)
Example

ExampleNew 演示创建验证器实例

package main

import (
	"fmt"

	"github.com/f2xme/gox/validator"
)

func main() {
	type Config struct {
		Host string `validate:"required,hostname"`
		Port int    `validate:"required,min=1,max=65535"`
	}

	v := validator.New()

	config := Config{
		Host: "localhost",
		Port: 8080,
	}

	if err := v.Validate(config); err != nil {
		fmt.Println("配置验证失败:", err)
	} else {
		fmt.Println("配置验证成功")
	}

}
Output:
配置验证成功

func (*Validator) RegisterTranslation

func (v *Validator) RegisterTranslation(tag, message string) error

RegisterTranslation 注册自定义验证规则的翻译消息。

tag 是验证标签名称,message 是错误消息模板。

示例:

v.RegisterTranslation("custom_username", "用户名格式不正确")

func (*Validator) RegisterValidation

func (v *Validator) RegisterValidation(tag string, fn validator.Func) error

RegisterValidation 注册自定义验证规则。

tag 是验证标签名称,fn 是验证函数。 验证函数返回 true 表示验证通过,false 表示验证失败。

示例:

v.RegisterValidation("custom_username", func(fl validator.FieldLevel) bool {
    username := fl.Field().String()
    return len(username) >= 3 && unicode.IsLetter(rune(username[0]))
})

type User struct {
    Username string `validate:"custom_username"`
}
Example

ExampleValidator_RegisterValidation 演示注册自定义验证规则

package main

import (
	"fmt"

	"github.com/f2xme/gox/validator"
	validatorv10 "github.com/go-playground/validator/v10"
)

func main() {
	type Product struct {
		SKU string `validate:"custom_sku"`
	}

	v := validator.New()

	// 注册自定义规则:SKU 必须是 6 位字母数字组合
	v.RegisterValidation("custom_sku", func(fl validatorv10.FieldLevel) bool {
		sku := fl.Field().String()
		if len(sku) != 6 {
			return false
		}
		for _, r := range sku {
			if !((r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9')) {
				return false
			}
		}
		return true
	})

	// 验证有效的 SKU
	product := Product{SKU: "ABC123"}
	if err := v.Validate(product); err != nil {
		fmt.Println("验证失败:", err)
	} else {
		fmt.Println("SKU 验证成功")
	}

}
Output:
SKU 验证成功

func (*Validator) Validate

func (v *Validator) Validate(i any) error

Validate 验证结构体字段是否符合标签定义的规则。

如果验证失败,返回包含所有错误信息的 error(中文描述)。 如果验证成功,返回 nil。

参数 i 应该是一个结构体或结构体指针。

示例:

type User struct {
    Name string `validate:"required"`
}
user := User{Name: ""}
err := v.Validate(user) // 返回错误:Name为必填字段

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL