前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go中最常用的数据校验库

Go中最常用的数据校验库

作者头像
fliter
发布2024-02-26 15:51:36
1430
发布2024-02-26 15:51:36
举报
文章被收录于专栏:旅途散记旅途散记

项目地址: github.com/go-playground/validator/v10

标记

标记说明

required

必填

Field或Struct validate:"required"

omitempty

空时忽略

Field或Struct validate:"omitempty"

len

长度

Field validate:"len=0"

eq

等于

Field validate:"eq=0"

gt

大于

Field validate:"gt=0"

gte

大于等于

Field validate:"gte=0"

lt

小于

Field validate:"lt=0"

lte

小于等于

Field validate:"lte=0"

eqfield

同一结构体字段相等

Field validate:"eqfield=Field2"

nefield

同一结构体字段不相等

Field validate:"nefield=Field2"

gtfield

大于同一结构体字段

Field validate:"gtfield=Field2"

gtefield

大于等于同一结构体字段

Field validate:"gtefield=Field2"

ltfield

小于同一结构体字段

Field validate:"ltfield=Field2"

ltefield

小于等于同一结构体字段

Field validate:"ltefield=Field2"

eqcsfield

跨不同结构体字段相等

Struct1.Field validate:"eqcsfield=Struct2.Field2"

necsfield

跨不同结构体字段不相等

Struct1.Field validate:"necsfield=Struct2.Field2"

gtcsfield

大于跨不同结构体字段

Struct1.Field validate:"gtcsfield=Struct2.Field2"

gtecsfield

大于等于跨不同结构体字段

Struct1.Field validate:"gtecsfield=Struct2.Field2"

ltcsfield

小于跨不同结构体字段

Struct1.Field validate:"ltcsfield=Struct2.Field2"

ltecsfield

小于等于跨不同结构体字段

Struct1.Field validate:"ltecsfield=Struct2.Field2"

min

最大值

Field validate:"min=1"

max

最小值

Field validate:"max=2"

structonly

仅验证结构体,不验证任何结构体字段

Struct validate:"structonly"

nostructlevel

不运行任何结构级别的验证

Struct validate:"nostructlevel"

dive

向下延伸验证,多层向下需要多个dive标记

[][]string validate:"gt=0,dive,len=1,dive,required"

dive Keys & EndKeys

与dive同时使用,用于对map对象的键的和值的验证,keys为键,endkeys为值

map[string]string validate:"gt=0,dive,keys,eq=1|eq=2,endkeys,required"

required_with

其他字段其中一个不为空且当前字段不为空

Field validate:"required_with=Field1 Field2"

required_with_all

其他所有字段不为空且当前字段不为空

Field validate:"required_with_all=Field1 Field2"

required_without

其他字段其中一个为空且当前字段不为空

Field `validate:"required_without=Field1 Field2"

required_without_all

其他所有字段为空且当前字段不为空

Field validate:"required_without_all=Field1 Field2"

isdefault

是默认值

Field validate:"isdefault=0"

oneof

其中之一

Field validate:"oneof=5 7 9"

containsfield

字段包含另一个字段

Field validate:"containsfield=Field2"

excludesfield

字段不包含另一个字段

Field validate:"excludesfield=Field2"

unique

是否唯一,通常用于切片或结构体

Field validate:"unique"

alphanum

字符串值是否只包含 ASCII 字母数字字符

Field validate:"alphanum"

alphaunicode

字符串值是否只包含 unicode 字符

Field validate:"alphaunicode"

alphanumunicode

字符串值是否只包含 unicode 字母数字字符

Field validate:"alphanumunicode"

numeric

字符串值是否包含基本的数值

Field validate:"numeric"

hexadecimal

字符串值是否包含有效的十六进制

Field validate:"hexadecimal"

hexcolor

字符串值是否包含有效的十六进制颜色

Field validate:"hexcolor"

lowercase

符串值是否只包含小写字符

Field validate:"lowercase"

uppercase

符串值是否只包含大写字符

Field validate:"uppercase"

email

字符串值包含一个有效的电子邮件

Field validate:"email"

json

字符串值是否为有效的 JSON

Field validate:"json"

file

符串值是否包含有效的文件路径,以及该文件是否存在于计算机上

Field validate:"file"

url

符串值是否包含有效的 url

Field validate:"url"

uri

符串值是否包含有效的 uri

Field validate:"uri"

base64

字符串值是否包含有效的 base64值

Field validate:"base64"

contains

字符串值包含子字符串值

Field validate:"contains=@"

containsany

字符串值包含子字符串值中的任何字符

Field validate:"containsany=abc"

containsrune

字符串值包含提供的特殊符号值

Field validate:"containsrune=☢"

excludes

字符串值不包含子字符串值

Field validate:"excludes=@"

excludesall

字符串值不包含任何子字符串值

Field validate:"excludesall=abc"

excludesrune

字符串值不包含提供的特殊符号值

Field validate:"containsrune=☢"

startswith

字符串以提供的字符串值开始

Field validate:"startswith=abc"

endswith

字符串以提供的字符串值结束

Field validate:"endswith=abc"

ip

字符串值是否包含有效的 IP 地址

Field validate:"ip"

ipv4

字符串值是否包含有效的 ipv4地址

Field validate:"ipv4"

datetime

字符串值是否包含有效的 日期

Field validate:"datetime"

单字段校验

模拟对前端传参进行校验

单字段多个条件 校验

代码语言:javascript
复制
package main

import (
 "fmt"
 "strings"

 "github.com/go-playground/locales/en"
 "github.com/go-playground/locales/zh"
 ut "github.com/go-playground/universal-translator"
 "github.com/go-playground/validator/v10"

 zhtrans "github.com/go-playground/validator/v10/translations/zh"
 // entrans "github.com/go-playground/validator/v10/translations/en"
)

/*
https://www.cnblogs.com/jiujuan/p/13823864.html

https://www.liwenzhou.com/posts/Go/validator-usages/

https://juejin.cn/post/7056823502640250893

https://juejin.cn/post/6847902214279659533
*/
type Student struct {
 Name  string `validate:required`
 Email string `validate:"email"`
 Age   int    `validate:"max=30,min=12"`
}

func main() {
 en := en.New() //英文翻译器
 zh := zh.New() //中文翻译器

 // 第一个参数是必填,如果没有其他的语言设置,就用这第一个
 // 后面的参数是支持多语言环境(
 // uni := ut.New(en, en) 也是可以的
 // uni := ut.New(en, zh, tw)
 uni := ut.New(en, zh)
 trans, _ := uni.GetTranslator("zh") //获取需要的语言

 student := Student{
  Name:  "tom",
  Email: "testemal",
  Age:   40,
 }
 validate := validator.New()

 zhtrans.RegisterDefaultTranslations(validate, trans)

 err := validate.Struct(student)
 if err != nil {
  // fmt.Println(err)

  errs := err.(validator.ValidationErrors)
  fmt.Println(removeStructName(errs.Translate(trans)))
 }
}

func removeStructName(fields map[string]string) map[string]string {
 result := map[string]string{}

 for field, err := range fields {
  result[field[strings.Index(field, ".")+1:]] = err
 }
 return result
}

在线代码[1]

输出:

map[Age:Age必须小于或等于30 Email:Email必须是一个有效的邮箱]

代码语言:javascript
复制
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"`
 Test      string               `validate:"len=0|min=6,max=24,len=0|alphanum"` // 或者 条件之一, 使用|。 但每个,都是独立的一个逻辑,之间是&的关系(有一个不满足就报错"Error:Field validation"),且条件没有传递,所以要在alphanum前面也加一个len=0|。 而max=24和长度为0不冲突,所以不需要加
 Products  []CreateOrderProduct `validate:"min=1"`                             // 产品列表
}

type CreateOrderProduct struct {
 SkuCode  string `json:"skuCode"`  // sku编码
 Quantity int64  `json:"quantity"` // 商品数量
}

//  oneof:只能是列举出的值其中一个,这些值必须是数值或字符串,以空格分隔,如果字符串中有空格,将字符串用单引号包围,validate:"oneof=red green"
// https://www.cnblogs.com/jiujuan/p/13823864.html

func main() {

 user := &User{
  FirstName: "Badger",
  LastName:  "Smith",
  Age:       115,
  Email:     "Badger.Smith@gmail.com",
  Test:      "",
  Products:  []CreateOrderProduct{},
 }

 validate := validator.New()
 err := validate.Struct(user)
 if err != nil {
  fmt.Println("=== error msg ====")
  fmt.Println(err)

  //if _, ok := err.(*validator.InvalidValidationError); ok {
  // fmt.Println(err)
  // return
  //}
  //
  //fmt.Println("\r\n=========== error field info ====================")
  //for _, err := range err.(validator.ValidationErrors) {
  // // 列出效验出错字段的信息
  // fmt.Println("Namespace: ", err.Namespace())
  // fmt.Println("Fild: ", err.Field())
  // fmt.Println("StructNamespace: ", err.StructNamespace())
  // fmt.Println("StructField: ", err.StructField())
  // fmt.Println("Tag: ", err.Tag())
  // fmt.Println("ActualTag: ", err.ActualTag())
  // fmt.Println("Kind: ", err.Kind())
  // fmt.Println("Type: ", err.Type())
  // fmt.Println("Value: ", err.Value())
  // fmt.Println("Param: ", err.Param())
  // fmt.Println()
  //}

  // from here you can create your own error messages in whatever language you wish
  return
 }
}

在线代码[2]

输出:

代码语言:javascript
复制
=== error msg ====
Key: 'User.Products' Error:Field validation for 'Products' failed on the 'min' tag

跨字段验证

eqfield 同一结构体字段验证相等

eqfield=Field:必须等于 Field 的值

最常见的就是输入2次密码验证

代码语言:javascript
复制
package main

import (
 "fmt"

 "github.com/go-playground/validator/v10"
)

// 多字段联合校验

// eqfield:同一结构体字段验证相等,最常见的就是输入2次密码验证

type Account struct {
 Name      string `validate:"lte=16"`
 Age       int    `validate:"min=20"`
 Password  string `validate:"min=8"`
 Password2 string `validate:"eqfield=Password"`
}

func main() {
 account := &Account{
  Name:      "Badger",
  Age:       115,
  Password:  "qwert12345",
  Password2: "111111",
 }

 validate := validator.New()
 err := validate.Struct(account)
 if err != nil {
  fmt.Println("=== error msg ====")
  fmt.Println(err)

  if _, ok := err.(*validator.InvalidValidationError); ok {
   fmt.Println(err)
   return
  }

  fmt.Println("\r\n=========== error field info ====================")
  for _, err := range err.(validator.ValidationErrors) {
   // 列出效验出错字段的信息
   fmt.Println("Namespace: ", err.Namespace())
   fmt.Println("Fild: ", err.Field())
   fmt.Println("StructNamespace: ", err.StructNamespace())
   fmt.Println("StructField: ", err.StructField())
   fmt.Println("Tag: ", err.Tag())
   fmt.Println("ActualTag: ", err.ActualTag())
   fmt.Println("Kind: ", err.Kind())
   fmt.Println("Type: ", err.Type())
   fmt.Println("Value: ", err.Value())
   fmt.Println("Param: ", err.Param())
   fmt.Println()
  }

  // from here you can create your own error messages in whatever language you wish
  return
 }
}

在线运行[3]

输出:

代码语言:javascript
复制
=== error msg ====
Key: 'Account.Password2' Error:Field validation for 'Password2' failed on the 'eqfield' tag

=========== error field info ====================
Namespace:  Account.Password2
Fild:  Password2
StructNamespace:  Account.Password2
StructField:  Password2
Tag:  eqfield
ActualTag:  eqfield
Kind:  string
Type:  string
Value:  111111
Param:  Password

nefield:同一结构体字段验证不相等

nefield=Field:必须不等于 Field 的值

例如,验证密码不能和用户名相同

代码语言:javascript
复制
package main

import (
 "fmt"

 "github.com/go-playground/validator/v10"
)

// 多字段联合校验

// eqfield:同一结构体字段验证相等,最常见的就是输入2次密码验证

type Account struct {
 Name     string `validate:"lte=16"`
 Age      int    `validate:"min=20"`
 Password string `validate:"min=1,nefield=Name"`
}

func main() {
 account := &Account{
  Name:     "Badger",
  Age:      115,
  Password: "Badger",
 }

 validate := validator.New()
 err := validate.Struct(account)
 if err != nil {
  fmt.Println("=== error msg ====")
  fmt.Println(err)

  if _, ok := err.(*validator.InvalidValidationError); ok {
   fmt.Println(err)
   return
  }

  fmt.Println("\r\n=========== error field info ====================")
  for _, err := range err.(validator.ValidationErrors) {
   // 列出效验出错字段的信息
   fmt.Println("Namespace: ", err.Namespace())
   fmt.Println("Fild: ", err.Field())
   fmt.Println("StructNamespace: ", err.StructNamespace())
   fmt.Println("StructField: ", err.StructField())
   fmt.Println("Tag: ", err.Tag())
   fmt.Println("ActualTag: ", err.ActualTag())
   fmt.Println("Kind: ", err.Kind())
   fmt.Println("Type: ", err.Type())
   fmt.Println("Value: ", err.Value())
   fmt.Println("Param: ", err.Param())
   fmt.Println()
  }

  // from here you can create your own error messages in whatever language you wish
  return
 }
}

输出:

代码语言:javascript
复制
=== error msg ====
Key: 'Account.Password' Error:Field validation for 'Password' failed on the 'nefield' tag

=========== error field info ====================
Namespace:  Account.Password
Fild:  Password
StructNamespace:  Account.Password
StructField:  Password
Tag:  nefield
ActualTag:  nefield
Kind:  string
Type:  string
Value:  Badger
Param:  Name

类似的还有

  • gtfield=Field:必须大于 Field 的值。
  • gtefield=Field: 必须大于等于 Field 的值。
  • ltfield=Field:必须小于 Field 的值。
  • ltefield=Field:必须小于等于 Field 的值。

eqcsfield=Other.Field:必须等于 struct Other 中 Field 的值。

用于验证跨结构体的两个字段是否相等,需要指定另一个字段的名称或路径作为参数,比如 eqcsfield=Other.Field 中的 Other.Field 就是指定的另一个字段。

在使用该选项时,会比较当前字段和指定的另一个字段的值是否相等,如果相等则验证通过,否则验证失败。这个选项通常用于验证密码和确认密码等类似的场景。

代码语言:javascript
复制
package main

import (
 "fmt"

 "github.com/go-playground/validator/v10"
)

type Struct1 struct {
 Field1  string `validate:"eqcsfield=Struct2.Field2""`
 Struct2 struct {
  Field2 string
 }
}

func main() {

 s := &Struct1{
  Field1:  "必须一致",
  Struct2: struct{ Field2 string }{Field2: "没有一致"},
 }

 validate := validator.New()
 err := validate.Struct(s)
 if err != nil {
  fmt.Println("=== error msg ====")
  fmt.Println(err)

  if _, ok := err.(*validator.InvalidValidationError); ok {
   fmt.Println(err)
   return
  }

  fmt.Println("\r\n=========== error field info ====================")
  for _, err := range err.(validator.ValidationErrors) {
   // 列出效验出错字段的信息
   fmt.Println("Namespace: ", err.Namespace())
   fmt.Println("Fild: ", err.Field())
   fmt.Println("StructNamespace: ", err.StructNamespace())
   fmt.Println("StructField: ", err.StructField())
   fmt.Println("Tag: ", err.Tag())
   fmt.Println("ActualTag: ", err.ActualTag())
   fmt.Println("Kind: ", err.Kind())
   fmt.Println("Type: ", err.Type())
   fmt.Println("Value: ", err.Value())
   fmt.Println("Param: ", err.Param())
   fmt.Println()
  }

  // from here you can create your own error messages in whatever language you wish
  return
 }
}

输出:

代码语言:javascript
复制
=== error msg ====
Key: 'Struct1.Field1' Error:Field validation for 'Field1' failed on the 'eqcsfield' tag

=========== error field info ====================
Namespace:  Struct1.Field1
Fild:  Field1
StructNamespace:  Struct1.Field1
StructField:  Field1
Tag:  eqcsfield
ActualTag:  eqcsfield
Kind:  string
Type:  string
Value:  必须一致
Param:  Struct2.Field2

看起来只支持嵌套结构体,不支持两个独立的结构体之间某个字段的比较

eqfieldeqcsfield 的区别在于它们用于比较的字段的位置不同:eqfield 比较的是同一个结构体中的两个字段的值,而 eqcsfield 比较的是当前结构体中的某个字段和另一个(子?)结构体中的字段的值

类似的还有

  • necsfield=Other.Field:必须不等于 struct Other 中 Field 的值。
  • gtcsfield=Other.Field:必须大于 struct Other 中 Field 的值;
  • gtecsfield=Other.Field:必须大于等于 struct Other 中 Field 的值。
  • ltcsfield=Other.Field:必须小于 struct Other 中 Field 的值。
  • ltecsfield=Other.Field:必须小于等于 struct Other 中 Field 的值。

如何比较两个独立结构体中某两个字段的值?


required_with=Field1 Field2:在 Field1 或者 Field2 存在时,必须;

required_with=Field2:在 Field2被填写(即不为空)时,Field1也必须不能为空

代码语言:javascript
复制
package main

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

type User struct {
    Name     string `validate:"required"`
    Email    string `validate:"required_with=Phone"`
    Phone    string
}

func main() {
    user1 := User{
        Name:     "John",
        Email:    "",
        Phone:    "",
    }

    user2 := User{
        Name:     "Mary",
        Email:    "mary@example.com",
        Phone:    "",
    }

    validate := validator.New()

    err1 := validate.Struct(user1)
    if err1 != nil {
        fmt.Println(err1)
    }

    err2 := validate.Struct(user2)
    if err2 != nil {
        fmt.Println(err2)
    }
}

验证通过~

在这个例子中,User 结构体包含 Name、Email 和 Phone 字段。Email 字段被标记为 required_with=Phone,这意味着当 Phone 字段被填写时,Email 字段也必须被填写。

而如果把user1改为:

代码语言:javascript
复制
user1 := User{
  Name:  "John",
  Email: "",
  Phone: "123",
 }

则会报错:

代码语言:javascript
复制
Key: 'User.Email' Error:Field validation for 'Email' failed on the 'required_with' tag

验证不通过


required_with_all=Field1 Field2:在 Field1 与 Field2 都存在时,必须;(仅当所有其他指定的字段都存在时,验证字段才必须存在)

要么有这个tag的全部为空,如果有一个不为空,那所有其他的也都不能为空~

代码语言:javascript
复制
package main

import (
 "fmt"

 "github.com/go-playground/validator/v10"
)

type User6 struct {
 Name  string `validate:"required"`
 Email string `validate:"required_with_all=Phone"`
 Phone string `validate:"required_with_all=Email"`
}

func main() {
 user := User6{
  Name:  "John",
  Email: "",
  Phone: "",
 }

 validate := validator.New()

 err := validate.Struct(user)
 if err != nil {
  fmt.Println(err)
 }
}

Email 和 Phone 字段都被标记为 required_with_all,

这意味着当 Email 和 Phone

  • 要么全都为空
  • 如果其中的任何一个被填写时,另一个也必须被填写(不为空即可,可以不一样)

所以上面代码可以验证通过

如下也是合法的:

代码语言:javascript
复制
package main

import (
 "fmt"

 "github.com/go-playground/validator/v10"
)

type User6 struct {
 Name  string `validate:"required"`
 Email string `validate:"required_with_all=Phone"`
 Phone string `validate:"required_with_all=Email"`
}

func main() {
 user := User6{
  Name:  "John",
  Email: "1",
  Phone: "2",
 }

 validate := validator.New()

 err := validate.Struct(user)
 if err != nil {
  fmt.Println(err)
 }
}

类似的还有:

required_without=Field1 Field2:在 Field1 或者 Field2 不存在时,必须;

Field1 Field2字段其中(至少)一个为空,则当前字段不能为空

代码语言:javascript
复制
package main

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

type User struct {
    Name     string `validate:"required"`
    Email    string
    Phone    string
    Address  string `validate:"required_without=Email Phone"`// Email Phone 中间不能加逗号
}

func main() {
    user1 := User{
        Name:     "John",
        Email:    "",
        Phone:    "",
        Address:  "123 Main St.",
    }

    user2 := User{
        Name:     "Mary",
        Email:    "mary@example.com",
        Phone:    "",
        Address:  "",
    }

    validate := validator.New()

    err1 := validate.Struct(user1)
    if err1 != nil {
        fmt.Println("err1:", err1)
    }

    err2 := validate.Struct(user2)
    if err2 != nil {
       fmt.Println("err2:", err2)
    }
}

输出:

代码语言:javascript
复制
err2: Key: 'User7.Address' Error:Field validation for 'Address' failed on the 'required_without' tag

User 结构体包含 Name、Email、Phone 和 Address 字段。Address 字段被标记为 required_without=Email Phone,这意味着当 Email 和 Phone 字段至少一个为空时,Address 字段必须被填写。

required_without_all=Field1 Field2:在 Field1 与 Field2 都存在时,必须; (仅当所有其他指定字段都不存在时,验证字段才必须...)

Field1 Field2字段都为空时,则当前字段不能为空

代码语言:javascript
复制
package main

import (
 "fmt"

 "github.com/go-playground/validator/v10"
)

type User7 struct {
 Name    string `validate:"required"`
 Email   string
 Phone   string
 Address string `validate:"required_without_all=Email Phone"`
}

func main() {
 user1 := User7{
  Name:    "John",
  Email:   "",
  Phone:   "111",
  Address: "123 Main St.",
 }

 user2 := User7{
  Name:    "Mary",
  Email:   "",
  Phone:   "",
  Address: "",
 }

 validate := validator.New()

 err1 := validate.Struct(user1)
 if err1 != nil {
  fmt.Println("err1:", err1)
 }

 err2 := validate.Struct(user2)
 if err2 != nil {
  fmt.Println("err2:", err2)
 }
}

输出:

代码语言:javascript
复制
err2: Key: 'User7.Address' Error:Field validation for 'Address' failed on the 'required_without_all' tag

验证proto

可参考 Go gRPC进阶-proto数据验证(九) [4]


更复杂的判断

代码语言:javascript
复制
type User struct {
Age uint8 validate:"gte=0,lte=130"
Email string validate:"required,email"
Score int validate:"min=1" // 分数
Gender string validate:"required,oneof=男 女"
}

如果满足以下任意一项则认为通过:

  • Gender=男,Age小于35,Score大于60
  • Gender=女,Age小于40,Score大于50

这种用validator/v10能判断吗?..

这种复杂的验证规则超出了validator/v10的基本功能,需要进行自定义验证函数。可以使用validator/v10的Func函数,通过编写自定义的验证函数来实现这种验证规则。

如下是一个示例代码:

代码语言:javascript
复制
package main

import (
 "fmt"

 "github.com/go-playground/validator/v10"
)

type User struct {
 Age    uint8  `validate:"gte=0,lte=130,customValidation"`
 Email  string `validate:"required,email"`
 Score  int    `validate:"required,gte=0,customValidation"`
 Gender string `validate:"required,oneof=男 女,customValidation"`
}

func validateUser(fl validator.FieldLevel) bool {

 user, ok := fl.Top().Interface().(*User)

 fmt.Println("user is:", user)

 if !ok {
  return false
 }

 if user.Gender == "男" && user.Age < 35 && user.Score > 60 {
  return true
 }
 if user.Gender == "女" && user.Age < 40 && user.Score > 50 {
  return true
 }
 return false
}

// - Gender=男,Age小于35,Score大于60
// - Gender=女,Age小于40,Score大于50

func main() {
 user := &User{
  Age:    36,
  Email:  "example@gmail.com",
  Score:  1711,
  Gender: "男",
 }

 validate := validator.New()
 err := validate.RegisterValidation("customValidation", validateUser)
 if err != nil {
  fmt.Println(err)
  return
 }

 err = validate.Struct(user)

 fmt.Println("err is:", err)
 if err != nil {
  fmt.Println(err)
  return
 }

 fmt.Println("validation succeeded")
}

输出:

代码语言:javascript
复制
user is: &{36 example@gmail.com 1711 男}
user is: &{36 example@gmail.com 1711 男}
user is: &{36 example@gmail.com 1711 男}
err is: Key: 'User.Age' Error:Field validation for 'Age' failed on the 'customValidation' tag
Key: 'User.Score' Error:Field validation for 'Score' failed on the 'customValidation' tag
Key: 'User.Gender' Error:Field validation for 'Gender' failed on the 'customValidation' tag
Key: 'User.Age' Error:Field validation for 'Age' failed on the 'customValidation' tag
Key: 'User.Score' Error:Field validation for 'Score' failed on the 'customValidation' tag
Key: 'User.Gender' Error:Field validation for 'Gender' failed on the 'customValidation' tag

参考资料:

golang之验证器validator[5]

【Go】数据验证-validator[6]

Go 使用validator进行后端数据校验[7]

gopkg.in/go-playground/validator.v10[8]

结构字段验证--validator.v9[9]

Golang验证器之validator使用详解[10]

Go 每日一库之 validator[11]

golang常用库:字段参数验证库-validator使用[12]

参考资料

[1]

在线代码: https://go.dev/play/p/p0r79v_RuSO

[2]

在线代码: https://go.dev/play/p/tjZ6PurLe-p

[3]

在线运行: https://go.dev/play/p/UNj1WhSY1fM

[4]

Go gRPC进阶-proto数据验证(九) : https://www.cnblogs.com/FireworksEasyCool/p/12761033.html

[5]

golang之验证器validator: https://www.cnblogs.com/xingxia/p/golang_validator.html

[6]

【Go】数据验证-validator: https://blog.csdn.net/qq_42887507/article/details/120934568

[7]

Go 使用validator进行后端数据校验: https://www.admpub.com/blog/post/admin/Go-%E4%BD%BF%E7%94%A8validator%E8%BF%9B%E8%A1%8C%E5%90%8E%E7%AB%AF%E6%95%B0%E6%8D%AE%E6%A0%A1%E9%AA%8C

[8]

gopkg.in/go-playground/validator.v10: https://pkg.go.dev/gopkg.in/go-playground/validator.v10

[9]

结构字段验证--validator.v9: https://www.cnblogs.com/zhzhlong/p/10033234.html

[10]

Golang验证器之validator使用详解: https://www.jb51.net/article/260639.htm

[11]

Go 每日一库之 validator: https://darjun.github.io/2020/04/04/godailylib/validator/

[12]

golang常用库:字段参数验证库-validator使用: https://www.cnblogs.com/jiujuan/p/13823864.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 旅途散记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单字段校验
    • 单字段多个条件 校验
    • 跨字段验证
      • eqfield 同一结构体字段验证相等
        • nefield:同一结构体字段验证不相等
          • eqcsfield=Other.Field:必须等于 struct Other 中 Field 的值。
            • required_with=Field1 Field2:在 Field1 或者 Field2 存在时,必须;
              • required_with_all=Field1 Field2:在 Field1 与 Field2 都存在时,必须;(仅当所有其他指定的字段都存在时,验证字段才必须存在)
                • required_without=Field1 Field2:在 Field1 或者 Field2 不存在时,必须;
                  • required_without_all=Field1 Field2:在 Field1 与 Field2 都存在时,必须; (仅当所有其他指定字段都不存在时,验证字段才必须...)
                  • 验证proto
                  • 更复杂的判断
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档