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 ¶
RegisterTranslation 在默认验证器上注册自定义翻译消息。
这是一个便捷函数,内部使用全局默认验证器实例。
示例:
validator.RegisterTranslation("phone", "手机号格式不正确")
func RegisterValidation ¶
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 ¶
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
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 ¶
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 ¶
RegisterTranslation 注册自定义验证规则的翻译消息。
tag 是验证标签名称,message 是错误消息模板。
示例:
v.RegisterTranslation("custom_username", "用户名格式不正确")
func (*Validator) RegisterValidation ¶
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 验证成功