一个用于字符串、数字、切片和结构体的校验库和过滤库。基于validator.js

安装

在终端中输入以下命令:

  1. go get github.com/asaskevich/govalidator

或者你可以get指定版本的包与gopkg.in:

  1. go get gopkg.in/asaskevich/govalidator.v10

开启此功能,默认情况下会校验所有字段

SetFieldsRequiredByDefault

当结构体中的字段不包括valid或未明确标记为忽略(即使用valid:"-"valid:"email,optional")都会导致校验失败,另外开启此功能的话可以把它放在一个包的 init() 方法或main()方法。

SetNilPtrAllowedByRequired

允许结构体中required标记的字段为nil。默认情况下,为了保持一致性,会禁用此功能。但是一些在nil值和zero value中间状态的值的包是可以使用的。如果禁用的话,nil值和zero值都会校验失败。

  1. import "github.com/asaskevich/govalidator"
  2. func init() {
  3. govalidator.SetFieldsRequiredByDefault(true)
  4. }

下面是一些代码示例:

  1. // 这个使用govalidator.ValidateStruct()会校验失败(参数的值不匹配)
  2. type exampleStruct struct {
  3. Name string ``
  4. Email string `valid:"email"`
  5. }
  6. // 当email为空或无效地址的话会校验失败
  7. type exampleStruct2 struct {
  8. Name string `valid:"-"`
  9. Email string `valid:"email"`
  10. }
  11. // email不为空且地址无效会校验失败
  12. type exampleStruct2 struct {
  13. Name string `valid:"-"`
  14. Email string `valid:"email,optional"`
  15. }

最近的重大更改(见#123)

自定义validator函数

可以将context上下文作为第二个参数,如果以struct对象传参的话就会被校验-这使得依赖验证成为可能。。

  1. import "github.com/asaskevich/govalidator"
  2. // 旧函数签名
  3. func(i interface{}) bool
  4. // 新函数签名
  5. func(i interface{}, o interface{}) bool

添加自定义validator

这是为了防止访问自定义validator时出现数据竞争。

  1. import "github.com/asaskevich/govalidator"
  2. // 旧的方法
  3. govalidator.CustomTypeTagMap["customByteArrayValidator"] = func(i interface{}, o interface{}) bool {
  4. // ...
  5. }
  6. // 新的方法
  7. govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, o interface{}) bool {
  8. // ...
  9. })

函数列表

  1. func Abs(value float64) float64
  2. func BlackList(str, chars string) string
  3. func ByteLength(str string, params ...string) bool
  4. func CamelCaseToUnderscore(str string) string
  5. func Contains(str, substring string) bool
  6. func Count(array []interface{}, iterator ConditionIterator) int
  7. func Each(array []interface{}, iterator Iterator)
  8. func ErrorByField(e error, field string) string
  9. func ErrorsByField(e error) map[string]string
  10. func Filter(array []interface{}, iterator ConditionIterator) []interface{}
  11. func Find(array []interface{}, iterator ConditionIterator) interface{}
  12. func GetLine(s string, index int) (string, error)
  13. func GetLines(s string) []string
  14. func HasLowerCase(str string) bool
  15. func HasUpperCase(str string) bool
  16. func HasWhitespace(str string) bool
  17. func HasWhitespaceOnly(str string) bool
  18. func InRange(value interface{}, left interface{}, right interface{}) bool
  19. func InRangeFloat32(value, left, right float32) bool
  20. func InRangeFloat64(value, left, right float64) bool
  21. func InRangeInt(value, left, right interface{}) bool
  22. func IsASCII(str string) bool
  23. func IsAlpha(str string) bool
  24. func IsAlphanumeric(str string) bool
  25. func IsBase64(str string) bool
  26. func IsByteLength(str string, min, max int) bool
  27. func IsCIDR(str string) bool
  28. func IsCRC32(str string) bool
  29. func IsCRC32b(str string) bool
  30. func IsCreditCard(str string) bool
  31. func IsDNSName(str string) bool
  32. func IsDataURI(str string) bool
  33. func IsDialString(str string) bool
  34. func IsDivisibleBy(str, num string) bool
  35. func IsEmail(str string) bool
  36. func IsExistingEmail(email string) bool
  37. func IsFilePath(str string) (bool, int)
  38. func IsFloat(str string) bool
  39. func IsFullWidth(str string) bool
  40. func IsHalfWidth(str string) bool
  41. func IsHash(str string, algorithm string) bool
  42. func IsHexadecimal(str string) bool
  43. func IsHexcolor(str string) bool
  44. func IsHost(str string) bool
  45. func IsIP(str string) bool
  46. func IsIPv4(str string) bool
  47. func IsIPv6(str string) bool
  48. func IsISBN(str string, version int) bool
  49. func IsISBN10(str string) bool
  50. func IsISBN13(str string) bool
  51. func IsISO3166Alpha2(str string) bool
  52. func IsISO3166Alpha3(str string) bool
  53. func IsISO4217(str string) bool
  54. func IsISO693Alpha2(str string) bool
  55. func IsISO693Alpha3b(str string) bool
  56. func IsIn(str string, params ...string) bool
  57. func IsInRaw(str string, params ...string) bool
  58. func IsInt(str string) bool
  59. func IsJSON(str string) bool
  60. func IsLatitude(str string) bool
  61. func IsLongitude(str string) bool
  62. func IsLowerCase(str string) bool
  63. func IsMAC(str string) bool
  64. func IsMD4(str string) bool
  65. func IsMD5(str string) bool
  66. func IsMagnetURI(str string) bool
  67. func IsMongoID(str string) bool
  68. func IsMultibyte(str string) bool
  69. func IsNatural(value float64) bool
  70. func IsNegative(value float64) bool
  71. func IsNonNegative(value float64) bool
  72. func IsNonPositive(value float64) bool
  73. func IsNotNull(str string) bool
  74. func IsNull(str string) bool
  75. func IsNumeric(str string) bool
  76. func IsPort(str string) bool
  77. func IsPositive(value float64) bool
  78. func IsPrintableASCII(str string) bool
  79. func IsRFC3339(str string) bool
  80. func IsRFC3339WithoutZone(str string) bool
  81. func IsRGBcolor(str string) bool
  82. func IsRegex(str string) bool
  83. func IsRequestURI(rawurl string) bool
  84. func IsRequestURL(rawurl string) bool
  85. func IsRipeMD128(str string) bool
  86. func IsRipeMD160(str string) bool
  87. func IsRsaPub(str string, params ...string) bool
  88. func IsRsaPublicKey(str string, keylen int) bool
  89. func IsSHA1(str string) bool
  90. func IsSHA256(str string) bool
  91. func IsSHA384(str string) bool
  92. func IsSHA512(str string) bool
  93. func IsSSN(str string) bool
  94. func IsSemver(str string) bool
  95. func IsTiger128(str string) bool
  96. func IsTiger160(str string) bool
  97. func IsTiger192(str string) bool
  98. func IsTime(str string, format string) bool
  99. func IsType(v interface{}, params ...string) bool
  100. func IsURL(str string) bool
  101. func IsUTFDigit(str string) bool
  102. func IsUTFLetter(str string) bool
  103. func IsUTFLetterNumeric(str string) bool
  104. func IsUTFNumeric(str string) bool
  105. func IsUUID(str string) bool
  106. func IsUUIDv3(str string) bool
  107. func IsUUIDv4(str string) bool
  108. func IsUUIDv5(str string) bool
  109. func IsULID(str string) bool
  110. func IsUnixTime(str string) bool
  111. func IsUpperCase(str string) bool
  112. func IsVariableWidth(str string) bool
  113. func IsWhole(value float64) bool
  114. func LeftTrim(str, chars string) string
  115. func Map(array []interface{}, iterator ResultIterator) []interface{}
  116. func Matches(str, pattern string) bool
  117. func MaxStringLength(str string, params ...string) bool
  118. func MinStringLength(str string, params ...string) bool
  119. func NormalizeEmail(str string) (string, error)
  120. func PadBoth(str string, padStr string, padLen int) string
  121. func PadLeft(str string, padStr string, padLen int) string
  122. func PadRight(str string, padStr string, padLen int) string
  123. func PrependPathToErrors(err error, path string) error
  124. func Range(str string, params ...string) bool
  125. func RemoveTags(s string) string
  126. func ReplacePattern(str, pattern, replace string) string
  127. func Reverse(s string) string
  128. func RightTrim(str, chars string) string
  129. func RuneLength(str string, params ...string) bool
  130. func SafeFileName(str string) string
  131. func SetFieldsRequiredByDefault(value bool)
  132. func SetNilPtrAllowedByRequired(value bool)
  133. func Sign(value float64) float64
  134. func StringLength(str string, params ...string) bool
  135. func StringMatches(s string, params ...string) bool
  136. func StripLow(str string, keepNewLines bool) string
  137. func ToBoolean(str string) (bool, error)
  138. func ToFloat(str string) (float64, error)
  139. func ToInt(value interface{}) (res int64, err error)
  140. func ToJSON(obj interface{}) (string, error)
  141. func ToString(obj interface{}) string
  142. func Trim(str, chars string) string
  143. func Truncate(str string, length int, ending string) string
  144. func TruncatingErrorf(str string, args ...interface{}) error
  145. func UnderscoreToCamelCase(s string) string
  146. func ValidateMap(inputMap map[string]interface{}, validationMap map[string]interface{}) (bool, error)
  147. func ValidateStruct(s interface{}) (bool, error)
  148. func WhiteList(str, chars string) string
  149. type ConditionIterator
  150. type CustomTypeValidator
  151. type Error
  152. func (e Error) Error() string
  153. type Errors
  154. func (es Errors) Error() string
  155. func (es Errors) Errors() []error
  156. type ISO3166Entry
  157. type ISO693Entry
  158. type InterfaceParamValidator
  159. type Iterator
  160. type ParamValidator
  161. type ResultIterator
  162. type UnsupportedTypeError
  163. func (e *UnsupportedTypeError) Error() string
  164. type Validator

例子

判断是否为URL(IsURL)

  1. println(govalidator.IsURL(`http://user@pass:domain.com/path/page`)) // false

判断类型(IsType)

  1. println(govalidator.IsType("Bob", "string")) // true
  2. println(govalidator.IsType(1, "int")) // true
  3. i := 1
  4. println(govalidator.IsType(&i, "*int")) // true

IsType也可以在struct tag 用type使用, 这对map校验很有必要的:

  1. type User struct {
  2. Name string `valid:"type(string)"`
  3. Age int `valid:"type(int)"`
  4. Meta interface{} `valid:"type(string)"`
  5. }
  6. result, err := govalidator.ValidateStruct(User{"Bob", 20, "meta"})
  7. if err != nil {
  8. println("error: " + err.Error())
  9. }
  10. println(result) // true

ToString

  1. type User struct {
  2. FirstName string
  3. LastName string
  4. }
  5. str := govalidator.ToString(User{"John", "Juan"})
  6. println(str) // {John Juan}

遍历(Each),Map,过滤,切片计数

遍历迭代array和slice会调用Iterator

  1. data := []interface{}{1, 2, 3}
  2. var fn govalidator.Iterator = func(value interface{}, index int) {
  3. println(value.(int))
  4. }
  5. govalidator.Each(data, fn)
  6. //1
  7. //2
  8. //3
  1. data := []interface{}{1, 2, 3, 4, 5}
  2. var fn govalidator.ResultIterator = func(value interface{}, index int) interface{} {
  3. return value.(int) * 3
  4. }
  5. _ = govalidator.Map(data, fn) // result = []interface{}{1, 6, 9, 12, 15}
  1. data := []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
  2. var fn govalidator.ConditionIterator = func(value interface{}, index int) bool {
  3. return value.(int)%2 == 0
  4. }
  5. _ = govalidator.Filter(data, fn) // result = []interface{}{2, 4, 6, 8, 10}
  6. _ = govalidator.Count(data, fn) // result = 5

校验struct

如果要校验structs,你可以在struct的任何字段中使用valid tag。使用此字段的所有validator在一个tag中均按逗号进行分隔。如果你想跳过校验,请将-放在你的tag中。如果下面列表中没有你需要的validator,你可以按下面例子添加:

  1. govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
  2. return str == "duck"
  3. })

有关完全自定义validator(基于接口),请参阅下文。

下面是在结构体字段中的可以使用的validator列表(validator - 使用方法):

  1. "email": IsEmail,
  2. "url": IsURL,
  3. "dialstring": IsDialString,
  4. "requrl": IsRequestURL,
  5. "requri": IsRequestURI,
  6. "alpha": IsAlpha,
  7. "utfletter": IsUTFLetter,
  8. "alphanum": IsAlphanumeric,
  9. "utfletternum": IsUTFLetterNumeric,
  10. "numeric": IsNumeric,
  11. "utfnumeric": IsUTFNumeric,
  12. "utfdigit": IsUTFDigit,
  13. "hexadecimal": IsHexadecimal,
  14. "hexcolor": IsHexcolor,
  15. "rgbcolor": IsRGBcolor,
  16. "lowercase": IsLowerCase,
  17. "uppercase": IsUpperCase,
  18. "int": IsInt,
  19. "float": IsFloat,
  20. "null": IsNull,
  21. "uuid": IsUUID,
  22. "uuidv3": IsUUIDv3,
  23. "uuidv4": IsUUIDv4,
  24. "uuidv5": IsUUIDv5,
  25. "creditcard": IsCreditCard,
  26. "isbn10": IsISBN10,
  27. "isbn13": IsISBN13,
  28. "json": IsJSON,
  29. "multibyte": IsMultibyte,
  30. "ascii": IsASCII,
  31. "printableascii": IsPrintableASCII,
  32. "fullwidth": IsFullWidth,
  33. "halfwidth": IsHalfWidth,
  34. "variablewidth": IsVariableWidth,
  35. "base64": IsBase64,
  36. "datauri": IsDataURI,
  37. "ip": IsIP,
  38. "port": IsPort,
  39. "ipv4": IsIPv4,
  40. "ipv6": IsIPv6,
  41. "dns": IsDNSName,
  42. "host": IsHost,
  43. "mac": IsMAC,
  44. "latitude": IsLatitude,
  45. "longitude": IsLongitude,
  46. "ssn": IsSSN,
  47. "semver": IsSemver,
  48. "rfc3339": IsRFC3339,
  49. "rfc3339WithoutZone": IsRFC3339WithoutZone,
  50. "ISO3166Alpha2": IsISO3166Alpha2,
  51. "ISO3166Alpha3": IsISO3166Alpha3,
  52. "ulid": IsULID,

带参数的validator

  1. "range(min|max)": Range,"length(min|max)": ByteLength,"runelength(min|max)": RuneLength,"stringlength(min|max)": StringLength,"matches(pattern)": StringMatches,"in(string1|string2|...|stringN)": IsIn,"rsapub(keylength)" : IsRsaPub,"minstringlength(int): MinStringLength,"maxstringlength(int): MaxStringLength,

带任何类型参数的validator

  1. "type(type)": IsType,

下面是使用的小例子:

  1. type Post struct {
  2. Title string `valid:"alphanum,required"`
  3. Message string `valid:"duck,ascii"`
  4. Message2 string `valid:"animal(dog)"`
  5. AuthorIP string `valid:"ipv4"`
  6. Date string `valid:"-"`
  7. }
  8. post := &Post{
  9. Title: "My Example Post",
  10. Message: "duck",
  11. Message2: "dog",
  12. AuthorIP: "123.234.54.3",
  13. }
  14. // 可以添加自己想要检验的tags
  15. govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
  16. return str == "duck"
  17. })
  18. // 可以添加自己想要检验的参数tags
  19. govalidator.ParamTagMap["animal"] = govalidator.ParamValidator(func(str string, params ...string) bool {
  20. species := params[0]
  21. return str == species
  22. })
  23. govalidator.ParamTagRegexMap["animal"] = regexp.MustCompile("^animal\\((\\w+)\\)$")
  24. result, err := govalidator.ValidateStruct(post)
  25. if err != nil {
  26. println("error: " + err.Error())
  27. }
  28. println(result)

校验Map

如果你想要校验Map,可以用需要校验的Map和包含在ValidateStruct使用的相同Tag的校验Map,并且两个Map必须是map[string]interface{}的类型

下面是使用的小例子:

  1. var mapTemplate = map[string]interface{}{
  2. "name":"required,alpha",
  3. "family":"required,alpha",
  4. "email":"required,email",
  5. "cell-phone":"numeric",
  6. "address":map[string]interface{}{
  7. "line1":"required,alphanum",
  8. "line2":"alphanum",
  9. "postal-code":"numeric",
  10. },
  11. }
  12. var inputMap = map[string]interface{}{
  13. "name":"Bob",
  14. "family":"Smith",
  15. "email":"foo@bar.baz",
  16. "address":map[string]interface{}{
  17. "line1":"",
  18. "line2":"",
  19. "postal-code":"",
  20. },
  21. }
  22. result, err := govalidator.ValidateMap(inputMap, mapTemplate)
  23. if err != nil {
  24. println("error: " + err.Error())
  25. }
  26. println(result)

白名单

  1. // 从一个string中移除a-z之外的所有字符
  2. println(govalidator.WhiteList("a3a43a5a4a3a2a23a4a5a4a3a4", "a-z") == "aaaaaaaaaaaa")

自定义校验函数

允许使用你自定义特定域的validators - 例子如下:

  1. import "github.com/asaskevich/govalidator"
  2. type CustomByteArray [6]byte // 支持自定义类型并可以进行校验
  3. type StructWithCustomByteArray struct {
  4. ID CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` // 多个自定义validator也是可以的,并将按顺序进行处理
  5. Email string `valid:"email"`
  6. CustomMinLength int `valid:"-"`
  7. }
  8. govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, context interface{}) bool {
  9. switch v := context.(type) {
  10. case StructWithCustomByteArray:
  11. case SomeOtherType:
  12. // ...
  13. default:
  14. //
  15. }
  16. switch v := i.(type) {
  17. case CustomByteArray:
  18. for _, e := range v {
  19. if e != 0 {
  20. return true
  21. }
  22. }
  23. }
  24. return false
  25. })
  26. govalidator.CustomTypeTagMap.Set("customMinLengthValidator", func(i interface{}, context interface{}) bool {
  27. switch v := context.(type) { // 会根据另一个字段中的值校验一个字段,即依赖的校验
  28. case StructWithCustomByteArray:
  29. return len(v.ID) >= v.CustomMinLength
  30. }
  31. return false
  32. })

遍历Error

默认情况下,Error()在单个字符串中返回所有错误。要获取每个error,可以这样做:

  1. if err != nil {
  2. errs := err.(govalidator.Errors).Errors()
  3. for _, e := range errs {
  4. fmt.Println(e.Error())
  5. }
  6. }

自定义error消息

通过添加~分隔号可以自定义错误消息-例子如下

  1. type Ticket struct {
  2. Id int64 `json:"id"`
  3. FirstName string `json:"firstname" valid:"required~First name is blank"`
  4. }

相关库比较

库名 介绍 star数
https://github.com/gookit/validate Go通用的数据验证与过滤库,使用简单,内置大部分常用验证、过滤器,支持自定义验证器、自定义消息、字段翻译。咱国人开发的。文档可参考 https://github.com/gookit/validate/blob/master/README.zh-CN.md 500
https://github.com/go-ozzo/ozzo-validation 一个常用的Go验证包。支持使用普通语言构造而不是容易出错的struct标记的可配置和可扩展的验证规则的校验库。 2.1k
https://github.com/go-playground/validator Go 结构体和字段校验库, 包括跨字段, 跨Struct, Map, Slice和Array。另外gin也默认支持。可参考大俊大佬Go 每日一库之 validator 7.8k
https://github.com/asaskevich/govalidator 一个用于字符串、数字、切片和结构体的校验库和过滤库。基于validator.js
4.7k