菜单

数据验证

相关源文件

此页面解释了 Gin 框架中的数据验证工作原理,重点介绍了在绑定后如何验证传入的请求数据。有关请求数据如何绑定到 Go 结构体的信息,请参阅 数据绑定

概述

Gin 中的数据验证建立在绑定系统之上,以确保绑定数据在处理前满足特定要求。验证系统利用 go-playground/validator 包,通过结构体标签声明式地应用广泛的验证规则。

来源: binding/binding.go50-66 binding/default_validator.go16-19

验证架构

StructValidator 接口

验证系统围绕 StructValidator 接口构建,该接口定义了验证器实现的契约。

StructValidator 接口有两个关键方法:

  • ValidateStruct(any) error:验证传入的值,并妥善处理各种类型。
  • Engine() any:返回底层验证引擎以供自定义。

来源: binding/binding.go50-66 binding/default_validator.go41-95

默认验证器实现

Gin 使用 go-playground/validator 包提供了 StructValidator 接口的默认实现。此实现:

  • 验证结构体、结构体指针、切片和数组。
  • 递归验证嵌套结构体和切片。
  • 使用 "binding" 标签名作为验证规则。
  • 延迟初始化以最大限度地减少开销。

默认验证器被设置为包级变量。

来源: binding/binding.go71 binding/default_validator.go44-95

验证过程

与绑定的集成

验证是绑定过程的最后一步。在将请求数据绑定到结构体后,会检查通过结构体标签指定的验证规则。

绑定系统使用此简单函数调用验证系统。

来源: binding/binding.go118-123

验证逻辑

默认验证器处理不同类型的值:

  • 对于结构体:直接验证结构体。
  • 对于指针:解引用后验证值。
  • 对于切片/数组:验证集合中的每个元素。
  • 对于其他类型:跳过验证。

在验证结构体时,它使用 go-playground/validator 包根据 binding 标签中指定的约束来检查字段。

来源: binding/default_validator.go44-79

验证标签

验证规则在结构体字段标签中使用 binding 标签名指定。多个验证规则可以用逗号分隔。

常用验证标签

标签描述示例
必需字段必须存在且不能为空。binding:"required"
max字符串的最大长度或数字的最大值。binding:"max=32"
min字符串的最小长度或数字的最小值。binding:"min=8"
gt大于(用于数字)。binding:"gt=0"
lt小于(用于数字)。binding:"lt=100"
eq等于(用于数字)。binding:"eq=42"
email必须是有效的电子邮件地址。binding:"email"
url必须是有效的 URL。binding:"url"
regexp必须匹配指定的正则表达式。binding:"regexp=^[a-z]+$"

带验证的示例结构体

来源: binding/binding_test.go38-39 binding/binding_test.go43 binding/default_validator_test.go51-52

自定义验证

注册自定义验证规则

您可以通过添加自定义验证规则来扩展验证系统。为此,您需要:

  1. 访问底层验证器引擎。
  2. 注册您的自定义验证函数。

示例:自定义验证函数

自定义验证函数必须符合验证器包的签名要求。以下是检查值是否不等于 1 的自定义验证函数的示例:

来源: binding/validate_test.go223-253

错误处理

验证错误类型

验证失败时,错误会根据被验证值的类型返回:

  • 对于单个结构体:返回一个验证错误,描述哪些字段的验证失败。
  • 对于切片/数组:返回一个 SliceValidationError,其中包含每个无效元素的错误。

SliceValidationError

对于切片/数组验证,使用 SliceValidationError 来收集每个无效元素的错误。

来源: binding/default_validator.go21-39 binding/default_validator_test.go12-47

在处理程序中使用验证

验证在绑定过程中自动发生。在您的处理程序中,您只需检查绑定是否返回错误即可。

禁用验证

如果您想跳过验证,可以暂时将 Validator 设置为 nil。

来源: binding/binding_test.go743-746

最佳实践

  1. 使用适当的标签:选择符合您业务需求的验证规则。
  2. 组合标签:可以对单个字段应用多个验证。
  3. 验证嵌套结构:验证器将递归地验证嵌套结构。
  4. 创建自定义验证器:对于复杂的验证规则,请注册自定义验证器。
  5. 提供有意义的错误消息:考虑将验证错误转换为用户友好的消息。