validator庫你知多少?govalidator了解一下
govalidator[1] 一個(gè)用于字符串、數(shù)字、切片和結(jié)構(gòu)體的校驗(yàn)庫和過濾庫。基于validator.js[2]。
安裝
在終端中輸入以下命令:
go get github.com/asaskevich/govalidator
或者你可以get指定版本的包與gopkg.in:
go get gopkg.in/asaskevich/govalidator.v10
開啟此功能,默認(rèn)情況下會(huì)校驗(yàn)所有字段
SetFieldsRequiredByDefault
當(dāng)結(jié)構(gòu)體中的字段不包括valid或未明確標(biāo)記為忽略(即使用valid:"-"或valid:"email,optional")都會(huì)導(dǎo)致校驗(yàn)失敗,另外開啟此功能的話可以把它放在一個(gè)包的 init() 方法或main()方法。
SetNilPtrAllowedByRequired
允許結(jié)構(gòu)體中required標(biāo)記的字段為nil。默認(rèn)情況下,為了保持一致性,會(huì)禁用此功能。但是一些在nil值和zero value中間狀態(tài)的值的包是可以使用的。如果禁用的話,nil值和zero值都會(huì)校驗(yàn)失敗。
import "github.com/asaskevich/govalidator"
func init() {
govalidator.SetFieldsRequiredByDefault(true)
}
下面是一些代碼示例:
// 這個(gè)使用govalidator.ValidateStruct()會(huì)校驗(yàn)失敗(參數(shù)的值不匹配)
type exampleStruct struct {
Name string ``
Email string `valid:"email"`
}
// 當(dāng)email為空或無效地址的話會(huì)校驗(yàn)失敗
type exampleStruct2 struct {
Name string `valid:"-"`
Email string `valid:"email"`
}
// email不為空且地址無效會(huì)校驗(yàn)失敗
type exampleStruct2 struct {
Name string `valid:"-"`
Email string `valid:"email,optional"`
}
最近的重大更改(見#123[3])
自定義validator函數(shù)
可以將context上下文作為第二個(gè)參數(shù),如果以struct對(duì)象傳參的話就會(huì)被校驗(yàn)-這使得依賴驗(yàn)證成為可能。。
import "github.com/asaskevich/govalidator"
// 舊函數(shù)簽名
func(i interface{}) bool
// 新函數(shù)簽名
func(i interface{}, o interface{}) bool
添加自定義validator
這是為了防止訪問自定義validator時(shí)出現(xiàn)數(shù)據(jù)競(jìng)爭(zhēng)。
import "github.com/asaskevich/govalidator"
// 舊的方法
govalidator.CustomTypeTagMap["customByteArrayValidator"] = func(i interface{}, o interface{}) bool {
// ...
}
// 新的方法
govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, o interface{}) bool {
// ...
})
函數(shù)列表
func Abs(value float64) float64
func BlackList(str, chars string) string
func ByteLength(str string, params ...string) bool
func CamelCaseToUnderscore(str string) string
func Contains(str, substring string) bool
func Count(array []interface{}, iterator ConditionIterator) int
func Each(array []interface{}, iterator Iterator)
func ErrorByField(e error, field string) string
func ErrorsByField(e error) map[string]string
func Filter(array []interface{}, iterator ConditionIterator) []interface{}
func Find(array []interface{}, iterator ConditionIterator) interface{}
func GetLine(s string, index int) (string, error)
func GetLines(s string) []string
func HasLowerCase(str string) bool
func HasUpperCase(str string) bool
func HasWhitespace(str string) bool
func HasWhitespaceOnly(str string) bool
func InRange(value interface{}, left interface{}, right interface{}) bool
func InRangeFloat32(value, left, right float32) bool
func InRangeFloat64(value, left, right float64) bool
func InRangeInt(value, left, right interface{}) bool
func IsASCII(str string) bool
func IsAlpha(str string) bool
func IsAlphanumeric(str string) bool
func IsBase64(str string) bool
func IsByteLength(str string, min, max int) bool
func IsCIDR(str string) bool
func IsCRC32(str string) bool
func IsCRC32b(str string) bool
func IsCreditCard(str string) bool
func IsDNSName(str string) bool
func IsDataURI(str string) bool
func IsDialString(str string) bool
func IsDivisibleBy(str, num string) bool
func IsEmail(str string) bool
func IsExistingEmail(email string) bool
func IsFilePath(str string) (bool, int)
func IsFloat(str string) bool
func IsFullWidth(str string) bool
func IsHalfWidth(str string) bool
func IsHash(str string, algorithm string) bool
func IsHexadecimal(str string) bool
func IsHexcolor(str string) bool
func IsHost(str string) bool
func IsIP(str string) bool
func IsIPv4(str string) bool
func IsIPv6(str string) bool
func IsISBN(str string, version int) bool
func IsISBN10(str string) bool
func IsISBN13(str string) bool
func IsISO3166Alpha2(str string) bool
func IsISO3166Alpha3(str string) bool
func IsISO4217(str string) bool
func IsISO693Alpha2(str string) bool
func IsISO693Alpha3b(str string) bool
func IsIn(str string, params ...string) bool
func IsInRaw(str string, params ...string) bool
func IsInt(str string) bool
func IsJSON(str string) bool
func IsLatitude(str string) bool
func IsLongitude(str string) bool
func IsLowerCase(str string) bool
func IsMAC(str string) bool
func IsMD4(str string) bool
func IsMD5(str string) bool
func IsMagnetURI(str string) bool
func IsMongoID(str string) bool
func IsMultibyte(str string) bool
func IsNatural(value float64) bool
func IsNegative(value float64) bool
func IsNonNegative(value float64) bool
func IsNonPositive(value float64) bool
func IsNotNull(str string) bool
func IsNull(str string) bool
func IsNumeric(str string) bool
func IsPort(str string) bool
func IsPositive(value float64) bool
func IsPrintableASCII(str string) bool
func IsRFC3339(str string) bool
func IsRFC3339WithoutZone(str string) bool
func IsRGBcolor(str string) bool
func IsRegex(str string) bool
func IsRequestURI(rawurl string) bool
func IsRequestURL(rawurl string) bool
func IsRipeMD128(str string) bool
func IsRipeMD160(str string) bool
func IsRsaPub(str string, params ...string) bool
func IsRsaPublicKey(str string, keylen int) bool
func IsSHA1(str string) bool
func IsSHA256(str string) bool
func IsSHA384(str string) bool
func IsSHA512(str string) bool
func IsSSN(str string) bool
func IsSemver(str string) bool
func IsTiger128(str string) bool
func IsTiger160(str string) bool
func IsTiger192(str string) bool
func IsTime(str string, format string) bool
func IsType(v interface{}, params ...string) bool
func IsURL(str string) bool
func IsUTFDigit(str string) bool
func IsUTFLetter(str string) bool
func IsUTFLetterNumeric(str string) bool
func IsUTFNumeric(str string) bool
func IsUUID(str string) bool
func IsUUIDv3(str string) bool
func IsUUIDv4(str string) bool
func IsUUIDv5(str string) bool
func IsULID(str string) bool
func IsUnixTime(str string) bool
func IsUpperCase(str string) bool
func IsVariableWidth(str string) bool
func IsWhole(value float64) bool
func LeftTrim(str, chars string) string
func Map(array []interface{}, iterator ResultIterator) []interface{}
func Matches(str, pattern string) bool
func MaxStringLength(str string, params ...string) bool
func MinStringLength(str string, params ...string) bool
func NormalizeEmail(str string) (string, error)
func PadBoth(str string, padStr string, padLen int) string
func PadLeft(str string, padStr string, padLen int) string
func PadRight(str string, padStr string, padLen int) string
func PrependPathToErrors(err error, path string) error
func Range(str string, params ...string) bool
func RemoveTags(s string) string
func ReplacePattern(str, pattern, replace string) string
func Reverse(s string) string
func RightTrim(str, chars string) string
func RuneLength(str string, params ...string) bool
func SafeFileName(str string) string
func SetFieldsRequiredByDefault(value bool)
func SetNilPtrAllowedByRequired(value bool)
func Sign(value float64) float64
func StringLength(str string, params ...string) bool
func StringMatches(s string, params ...string) bool
func StripLow(str string, keepNewLines bool) string
func ToBoolean(str string) (bool, error)
func ToFloat(str string) (float64, error)
func ToInt(value interface{}) (res int64, err error)
func ToJSON(obj interface{}) (string, error)
func ToString(obj interface{}) string
func Trim(str, chars string) string
func Truncate(str string, length int, ending string) string
func TruncatingErrorf(str string, args ...interface{}) error
func UnderscoreToCamelCase(s string) string
func ValidateMap(inputMap map[string]interface{}, validationMap map[string]interface{}) (bool, error)
func ValidateStruct(s interface{}) (bool, error)
func WhiteList(str, chars string) string
type ConditionIterator
type CustomTypeValidator
type Error
func (e Error) Error() string
type Errors
func (es Errors) Error() string
func (es Errors) Errors() []error
type ISO3166Entry
type ISO693Entry
type InterfaceParamValidator
type Iterator
type ParamValidator
type ResultIterator
type UnsupportedTypeError
func (e *UnsupportedTypeError) Error() string
type Validator
例子
判斷是否為URL(IsURL)
println(govalidator.IsURL(`http://user@pass:domain.com/path/page`)) // false
判斷類型(IsType)
println(govalidator.IsType("Bob", "string")) // true
println(govalidator.IsType(1, "int")) // true
i := 1
println(govalidator.IsType(&i, "*int")) // true
IsType也可以在struct tag 用type判斷, 這對(duì)map校驗(yàn)很有必要的:
type User struct {
Name string `valid:"type(string)"`
Age int `valid:"type(int)"`
Meta interface{} `valid:"type(string)"`
}
result, err := govalidator.ValidateStruct(User{"Bob", 20, "meta"})
if err != nil {
println("error: " + err.Error())
}
println(result) // true
ToString
type User struct {
FirstName string
LastName string
}
str := govalidator.ToString(User{"John", "Juan"})
println(str) // {John Juan}
遍歷(Each),Map,過濾,切片計(jì)數(shù)
遍歷迭代array和slice會(huì)調(diào)用Iterator
data := []interface{}{1, 2, 3}
var fn govalidator.Iterator = func(value interface{}, index int) {
println(value.(int))
}
govalidator.Each(data, fn)
//1
//2
//3
data := []interface{}{1, 2, 3, 4, 5}
var fn govalidator.ResultIterator = func(value interface{}, index int) interface{} {
return value.(int) * 3
}
_ = govalidator.Map(data, fn) // result = []interface{}{3, 6, 9, 12, 15}
data := []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var fn govalidator.ConditionIterator = func(value interface{}, index int) bool {
return value.(int)%2 == 0
}
_ = govalidator.Filter(data, fn) // result = []interface{}{2, 4, 6, 8, 10}
_ = govalidator.Count(data, fn) // result = 5
校驗(yàn)struct
如果要校驗(yàn)structs,你可以在struct的任何字段中使用valid tag。使用此字段的所有validator在一個(gè)tag中均按逗號(hào)進(jìn)行分隔。如果你想跳過校驗(yàn),請(qǐng)將-放在你的tag中。如果下面列表中沒有你需要的validator,你可以按下面例子添加:
govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
return str == "duck"
})
有關(guān)完全自定義validator(基于接口),請(qǐng)參閱下文。
下面是在結(jié)構(gòu)體字段中的可以使用的validator列表(validator - 使用方法):
"email": IsEmail,
"url": IsURL,
"dialstring": IsDialString,
"requrl": IsRequestURL,
"requri": IsRequestURI,
"alpha": IsAlpha,
"utfletter": IsUTFLetter,
"alphanum": IsAlphanumeric,
"utfletternum": IsUTFLetterNumeric,
"numeric": IsNumeric,
"utfnumeric": IsUTFNumeric,
"utfdigit": IsUTFDigit,
"hexadecimal": IsHexadecimal,
"hexcolor": IsHexcolor,
"rgbcolor": IsRGBcolor,
"lowercase": IsLowerCase,
"uppercase": IsUpperCase,
"int": IsInt,
"float": IsFloat,
"null": IsNull,
"uuid": IsUUID,
"uuidv3": IsUUIDv3,
"uuidv4": IsUUIDv4,
"uuidv5": IsUUIDv5,
"creditcard": IsCreditCard,
"isbn10": IsISBN10,
"isbn13": IsISBN13,
"json": IsJSON,
"multibyte": IsMultibyte,
"ascii": IsASCII,
"printableascii": IsPrintableASCII,
"fullwidth": IsFullWidth,
"halfwidth": IsHalfWidth,
"variablewidth": IsVariableWidth,
"base64": IsBase64,
"datauri": IsDataURI,
"ip": IsIP,
"port": IsPort,
"ipv4": IsIPv4,
"ipv6": IsIPv6,
"dns": IsDNSName,
"host": IsHost,
"mac": IsMAC,
"latitude": IsLatitude,
"longitude": IsLongitude,
"ssn": IsSSN,
"semver": IsSemver,
"rfc3339": IsRFC3339,
"rfc3339WithoutZone": IsRFC3339WithoutZone,
"ISO3166Alpha2": IsISO3166Alpha2,
"ISO3166Alpha3": IsISO3166Alpha3,
"ulid": IsULID,
帶參數(shù)的validator
"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,
帶任意類型參數(shù)的validator
"type(type)": IsType,
下面是使用的小例子:
type Post struct {
Title string `valid:"alphanum,required"`
Message string `valid:"duck,ascii"`
Message2 string `valid:"animal(dog)"`
AuthorIP string `valid:"ipv4"`
Date string `valid:"-"`
}
post := &Post{
Title: "My Example Post",
Message: "duck",
Message2: "dog",
AuthorIP: "123.234.54.3",
}
// 可以添加自己想要檢驗(yàn)的tags
govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool {
return str == "duck"
})
// 可以添加自己想要檢驗(yàn)的參數(shù)tags
govalidator.ParamTagMap["animal"] = govalidator.ParamValidator(func(str string, params ...string) bool {
species := params[0]
return str == species
})
govalidator.ParamTagRegexMap["animal"] = regexp.MustCompile("^animal\\((\\w+)\\)$")
result, err := govalidator.ValidateStruct(post)
if err != nil {
println("error: " + err.Error())
}
println(result)
校驗(yàn)Map
如果你想要校驗(yàn)Map,可以用需要校驗(yàn)的Map和包含在ValidateStruct使用的相同Tag的校驗(yàn)Map,并且兩個(gè)Map必須是map[string]interface{}的類型
下面是使用的小例子:
var mapTemplate = map[string]interface{}{
"name":"required,alpha",
"family":"required,alpha",
"email":"required,email",
"cell-phone":"numeric",
"address":map[string]interface{}{
"line1":"required,alphanum",
"line2":"alphanum",
"postal-code":"numeric",
},
}
var inputMap = map[string]interface{}{
"name":"Bob",
"family":"Smith",
"email":"[email protected]",
"address":map[string]interface{}{
"line1":"",
"line2":"",
"postal-code":"",
},
}
result, err := govalidator.ValidateMap(inputMap, mapTemplate)
if err != nil {
println("error: " + err.Error())
}
println(result)
白名單
// 從一個(gè)string中移除a-z之外的所有字符
println(govalidator.WhiteList("a3a43a5a4a3a2a23a4a5a4a3a4", "a-z") == "aaaaaaaaaaaa")
自定義校驗(yàn)函數(shù)
允許使用你自定義特定域的validators - 例子如下:
import "github.com/asaskevich/govalidator"
type CustomByteArray [6]byte // 支持自定義類型并可以進(jìn)行校驗(yàn)
type StructWithCustomByteArray struct {
ID CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` // 多個(gè)自定義validator也是可以的,并將按順序進(jìn)行處理
Email string `valid:"email"`
CustomMinLength int `valid:"-"`
}
govalidator.CustomTypeTagMap.Set("customByteArrayValidator", func(i interface{}, context interface{}) bool {
switch v := context.(type) {
case StructWithCustomByteArray:
case SomeOtherType:
// ...
default:
//
}
switch v := i.(type) {
case CustomByteArray:
for _, e := range v {
if e != 0 {
return true
}
}
}
return false
})
govalidator.CustomTypeTagMap.Set("customMinLengthValidator", func(i interface{}, context interface{}) bool {
switch v := context.(type) { // 會(huì)根據(jù)另一個(gè)字段中的值校驗(yàn)一個(gè)字段,即依賴的校驗(yàn)
case StructWithCustomByteArray:
return len(v.ID) >= v.CustomMinLength
}
return false
})
遍歷Error
默認(rèn)情況下,Error()在單個(gè)字符串中返回所有錯(cuò)誤。要獲取每個(gè)error,可以這樣做:
if err != nil {
errs := err.(govalidator.Errors).Errors()
for _, e := range errs {
fmt.Println(e.Error())
}
}
自定義error消息
通過添加~分隔號(hào)可以自定義錯(cuò)誤消息-例子如下
type Ticket struct {
Id int64 `json:"id"`
FirstName string `json:"firstname" valid:"required~First name is blank"`
}
相關(guān)庫比較
| 庫名 | 介紹 | star數(shù) |
|---|---|---|
| https://github.com/gookit/validate | Go通用的數(shù)據(jù)驗(yàn)證與過濾庫,使用簡(jiǎn)單,內(nèi)置大部分常用驗(yàn)證、過濾器,支持自定義驗(yàn)證器、自定義消息、字段翻譯。咱國人開發(fā)的。文檔可參考 https://github.com/gookit/validate/blob/master/README.zh-CN.md | 500 |
| https://github.com/go-ozzo/ozzo-validation | 一個(gè)常用的Go驗(yàn)證包。支持使用普通語言構(gòu)造而不是容易出錯(cuò)的struct標(biāo)記的可配置和可擴(kuò)展的驗(yàn)證規(guī)則的校驗(yàn)庫。 | 2.1k |
| https://github.com/go-playground/validator | Go 結(jié)構(gòu)體和字段校驗(yàn)庫, 包括跨字段, 跨Struct, Map, Slice和Array。另外gin也默認(rèn)支持。可參考大俊大佬Go 每日一庫之 validator | 7.8k |
| https://github.com/asaskevich/govalidator | 一個(gè)用于字符串、數(shù)字、切片和結(jié)構(gòu)體的校驗(yàn)庫和過濾庫?;?span style="font-weight: bold;color: rgb(255, 53, 2);">validator.js[4]。 | 4.7k |
參考資料
govalidator: https://github.com/asaskevich/govalidator
[2]validator.js: https://github.com/chriso/validator.js
[3]#123: https://github.com/asaskevich/govalidator/pull/123
[4]validator.js: https://github.com/chriso/validator.js
推薦閱讀
