GOの研究ノート - データ検証

GOの研究ノート - データ検証

この記事のテーマ:asaskevich / govalidatorに基づいてGolangデータの検証を実現

元の記事の小さな遅い兄弟、転載することを歓迎


ディレクトリ

▪。Asaskevich / govalidator導入
一致II。ストリング▪
▪3。構造体要素が一致する
▪4。構造体要素オプション検証
5。構造体ネスティングチェック▪
▪のVI。ネストされたオプションのチェックを実現することができない
▪VIIを。個人的なベストプラクティス
8▪。他の機能は
付録1.文字列の正当性チェック▪
▪付録2.構造体の要素の検証項目
付録3.データ特徴量マッチング▪
▪付録4種類の変換
充填、▪付録5.クリッピング処理を、トラバーサル


A. Asaskevich / govalidator紹介

godoc年には、類似したサードパーティのデータ検証モジュールの数に見つけることができますが、私は、その理由をasaskevich / govalidatorを使用することをお勧めします:

▷スターはほとんど、継続的に最新のリリースで
▷完璧な機能、使いやすさの
豊富な文字列の検証、データマッチングが▷、ステッチ加工切削加工
妥当性チェック構造体要素を支持し、ネストされたチェックをサポート▷
学習▷ソースの価値を、宝箱であります

// 下载
go get github.com/asaskevich/govalidator

、githubのを使用するためにチェックgodocをサポートするための機能の一覧を表示します。注

https://github.com/asaskevich/govalidator
https://godoc.org/github.com/asaskevich/govalidator

II。文字列一致

govalidatorは、簡単な例を固定するために、文字列マッチングの多種多様なサポートしています

package main

import (
    "fmt"
    "github.com/asaskevich/govalidator"
)

func main() {
    // 判断字符串值是否为合法的IPv4地址
    ip4 := "192.168.1.1"
    fmt.Println(govalidator.IsIPv4(ip4)) // true

    // 判断字符串值是否为合法的MAC
    mac := "aa:bb:cc:dd:ee:ffffff"
    fmt.Println(govalidator.IsMAC(mac)) // false

    // 判断数字是否在指定范围内
    dig := 101    // string类型也可以用
    fmt.Println(govalidator.InRange(dig, 0, 100)) // false
}

輸出

true
false
false

付録3で詳述可能な検証方法の完全なリストは、本明細書


三。構造体の要素の一致

govalidator具体的構造体の要素をチェックするための機能を提供

govalidator.ValidateStruct()

簡単な例

package main

import (
    "fmt"
    "github.com/asaskevich/govalidator"
)

type foo struct {
    A string `valid:"ipv4"`
    B string `valid:"mac"`
    C string `valid:"range(0|100)"`    // 也可以使用int类型
}

func main() {
    f := foo{
        A: "192.168.1.1",
        B: "aa:bb:cc:dd:ee:ffffff",
        C: "101",
    }

    result, err := govalidator.ValidateStruct(f)
    if err != nil {
        fmt.Println("error: " + err.Error())
    }
    fmt.Println(result)
}

輸出

error: B: aa:bb:cc:dd:ee:ffffff does not validate as mac;C: 101 does not validate as range(0|100)
false

注意:

▪構造体要素は、付録2に、この記事を参照して、すべての一般的に使用されるキャリブレーションをサポートしていない
構造体の要素が型をエクスポートする必要があります▪を、つまり、あなたは大文字で始める必要があり、govalidatorのみ無視する
▪構造体要素のマッチングがこのような範囲として、よりインテリジェントである(分|最大)サポートするだけでなく、文字列、int型をサポートするだけでなく


四。構造体の要素の任意の検証

BOOL govalidatorグローバル変数の型は、()関数govalidator.SetFieldsRequiredByDefaultによって設定することができます。

▷trueに設定すると有効なタグを定義していない場合、あなたはエラーを求めるプロンプトが表示されます
有効なタグ、ないエラーが定義されていない場合は、falseに設定した場合▷。デフォルト値はfalseです

ゼロ値に遭遇したときにエラーまたは認証が必要とされる:さらに、有効なタグは、配置が明示的粒子微細化度を制御することができます。この設定は、)(SetFieldsRequiredByDefaultをオーバーライドすることができます。そのため、有効なタグには、以下の文言です

`valid:""` // 等同于空tag,即``
`valid:"-"`
`valid:","`
`valid:",optional`
`valid:",required`

次に、テストは次の通りであった:構造体要素がヌル文字「A」(即ち、ゼロの値)であると仮定します

▷govalidator.SetFieldsRequiredByDefault(真)

`valid:""`    // 报错:All fields are required to at least have one validation defined
`valid:"-"`    // true
`valid:","`    // 报错:Missing required field
`valid:",optional`    // true
`valid:",required`    // 报错:non zero value required
`valid:"ipv4"`    // 报错:Missing required field
`valid:"ipv4,optional"`    // true
`valid:"ipv4,required"`    // 报错:non zero value required

▷govalidator.SetFieldsRequiredByDefault(偽)

`valid:""`    // true
`valid:"-"`    // true
`valid:","`    // true
`valid:",optional`    // true
`valid:",required`    // non zero value required
`valid:"ipv4"`    // true
`valid:"ipv4,optional"`    // true
`valid:"ipv4,required"`    // 报错:non zero value required

値構造体のIPv4アドレス文字列が有効でない場合、このような「192.168.1.1.1」として、(非空の文字列)の試験要素を続行

▷govalidator.SetFieldsRequiredByDefault(真)

`valid:""`    // 报错:All fields are required to at least have one validation defined
`valid:"-"`    // true
`valid:","`    // true
`valid:",optional`    // true
`valid:",required`    // true
`valid:"ipv4"`    // 报错:192.168.1.1.1 does not validate as ipv4
`valid:"ipv4,optional"`    // 报错:192.168.1.1.1 does not validate as ipv4
`valid:"ipv4,required"`    // 报错:192.168.1.1.1 does not validate as ipv4

▷govalidator.SetFieldsRequiredByDefault(偽):上記の試験結果と同一と

また、グローバル変数のパラメータが設定govalidator.SetNilPtrAllowedByRequired()によって、そこにあるが、著者はテストされ、そのための公式の説明に直接投稿していませんので、

// 来自github
SetNilPtrAllowedByRequired causes validation to pass when struct fields marked by required are set to nil. This is disabled by default for consistency, but some packages that need to be able to determine between nil and zero value state can use this. If disabled, both nil and zero values cause validation errors.

// 来自godoc
SetNilPtrAllowedByRequired causes validation to pass for nil ptrs when a field is set to required. The validation will still reject ptr fields in their zero value state. Example with this enabled:

type exampleStruct struct {
    Name *string `valid:"required"

With `Name` set to "", this will be considered invalid input and will cause a validation error. With `Name` set to nil, this will be considered valid by validation. By default this is disabled.

ファイブ。構造体の入れ子チェック

ネストされた要素名があるタイプを、エクスポートする必要があり、例えば、大文字で始まります

package main

import (
    "fmt"
    "github.com/asaskevich/govalidator"
)

type Foo struct {
    A string `valid:"ipv4"`
    B string `valid:"mac"`
    C int `valid:"range(0|100)"`
}

type bar struct {
    X string `valid:"ipv4"`
    Foo `valid:",required"`
}

func main() {
    govalidator.SetFieldsRequiredByDefault(true)

    b := bar{
        X: "192.168.1.1",
    }

    b.Foo.A = "192.168.1.1.1"
    b.Foo.B = "aa:bb:cc:dd:ee:ff"
    b.Foo.C = 100

    result, err := govalidator.ValidateStruct(b)
    if err != nil {
        fmt.Println("error: " + err.Error())
    }
    fmt.Println(result)
}

輸出

error: Foo.A: 192.168.1.1.1 does not validate as ipv4;A: 192.168.1.1.1 does not validate as ipv4
false

あなたがfooに要素名を設定することができますが、それはのような、大文字で開始する必要があります。注意

MyFoo Foo `valid:",required"`    // 正确,可以读取到
myFoo Foo `valid:",required"`    // 错误,无法读取到

VI。ネストされたオプションのチェックを達成することができません

例えば、この以下のようなオプションのチェックネストされた粒子サイズとして実現することができず、効果がありません

type bar struct {
    X string `valid:"ipv4"`
    Foo `valid:",optional"`    // 不可行
}

上記のコードは、実際にこのようなに変換されるので

type bar struct {
    X string `valid:"ipv4"`
    Foo.A string `valid:"ipv4"`
    Foo.B string `valid:"mac"`
    Foo.C int `valid:"range(0|100)"`
}

これは、Fooのフルまたはフルではないパリティを確認する方法はありませんにつながります


VII。個人的なベストプラクティス

暗黙のエラーの使用は一度設定するので、すべての明示的なチェックは、設定をお勧めします、検出することは困難です

(真の)Govalidator.SetFieldsRequiredByDefault▷
▷タグ有効文言:テープが必要な、例えば:

想做验证使用`valid:ipv4,required`
不想做验证使用`valid:",required"`

VIII。その他の機能

govalidatorチェック機能もそう公式ドキュメントのgithubのを参照してください、練習していない著者の深さによるカスタムタグとカスタム検証機能をサポートしています。

govalidatorチェックをサポートに加えて、さらに(公式サイトおよびドキュメントと比較して、この論文より詳細な分類godoc)この文書4,5の付録を参照してください、より広範な文字列の切断、加工、定期的および他の機能と同様に、変換関数のいくつかのタイプをサポートしています。実際には、包装の層、及び取引のいくつかの詳細を行うことですので、しかし、私は、これらの切断、加工、通常の関数の使用をお勧めしません、複雑ではありませんが、あなたは学ぶことができます。

私は、任意の関数のgovalidatorを使用した場合、最初に十分価値の学習と参照宝物の大規模かつ包括的なソースであるソース、見ていることを信じています。


付録1.正当性チェック文字列

以下、このようなIPv4形式かどうかなど、ビジネスレベルの法的なチェックは、URLのかどうか、あります

func IsBase64(str string) bool
func IsCIDR(str string) bool    // 是否为合法的CIDR格式,包含了IPv4与IPv6
func IsCreditCard(str string) bool
func IsDNSName(str string) bool
func IsDataURI(str string) bool
func IsEmail(str string) bool
func IsExistingEmail(email string) bool
func IsFilePath(str string) (bool, int)
func IsHash(str string, algorithm string) bool
func IsHexcolor(str string) bool
func IsHost(str string) bool
func IsIP(str string) bool    // 是否为合法的IP地址,包含了IPv4与IPv6
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 IsJSON(str string) bool    // 通过json.Unmarshal()是否返回error进行判断
func IsLatitude(str string) bool
func IsLongitude(str string) bool
func IsMAC(str string) bool    // 支持aa:bb:cc:dd:ee:ff,以及aabb.ccdd.eeff格式
func IsMongoID(str string) bool
func IsPort(str string) bool
func IsRFC3339(str string) bool
func IsRFC3339WithoutZone(str string) bool
func IsRGBcolor(str string) bool
func IsRequestURI(rawurl string) bool
func IsRequestURL(rawurl string) bool
func IsRsaPub(str string, params ...string) bool
func IsRsaPublicKey(str string, keylen int) bool
func IsSSN(str string) bool
func IsSemver(str string) bool
func IsTime(str string, format string) bool
func IsURL(str string) bool
func IsUUID(str string) bool    // 包含UUIDv3、UUIDv4、UUIDv5
func IsUUIDv3(str string) bool
func IsUUIDv4(str string) bool
func IsUUIDv5(str string) bool

検証項目の付録2.構造体の要素

2種類がありますが、最初のものが2番目の引数がバンドで、引数ではありません

▷最初:引数なしで(最初の列は有効なタグを作成する方法を示し、2番目の列は関数をエクスポートgovalidatorと同等のものを表します)

"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,

▷第二:パラメータ(最初の列は有効なタグを作成する方法を示し、2番目の列は関数をエクスポートgovalidatorと同等のものを表します)

"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,

付録3.データの特徴マッチング

以下の非データチェック動作は、等は、空白を含めるかどうか、固定された文字列に含まれる正の整数かどうか

func ByteLength(str string, params ...string) bool
func Contains(str, substring string) bool
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 IsByteLength(str string, min, max int) bool
func IsDialString(str string) bool
func IsDivisibleBy(str, num string) bool
func IsFloat(str string) bool
func IsFullWidth(str string) bool
func IsHalfWidth(str string) bool
func IsHexadecimal(str string) bool
func IsIn(str string, params ...string) bool
func IsInt(str string) bool
func IsLowerCase(str string) bool
func IsMultibyte(str string) bool
func IsNatural(value float64) bool
func IsNegative(value float64) bool
func IsNonNegative(value float64) bool // >=0
func IsNonPositive(value float64) bool // <=0
func IsNull(str string) bool // 空字符串
func IsNumeric(str string) bool // 字符串里仅包含数字
func IsPositive(value float64) bool // 正数
func IsPrintableASCII(str string) bool
func IsUTFDigit(str string) bool
func IsUTFLetter(str string) bool
func IsUTFLetterNumeric(str string) bool
func IsUTFNumeric(str string) bool
func IsUpperCase(str string) bool
func IsVariableWidth(str string) bool
func IsWhole(value float64) bool // 整数
func Matches(str, pattern string) bool // 正则匹配
func Range(str string, params ...string) bool // 字符串长度,params的string会转换成float64然后调用InRange(),主要是用于struct tag的range(min|max)
func RuneLength(str string, params ...string) bool // alias for StringLength
func Sign(value float64) float64 // 如果大于0则返回1,等于0返回0,小于0返回-1
func StringLength(str string, params ...string) bool // 字符串长度在指定范围内(视为utf8)
func StringMatches(s string, params ...string) bool // 正则匹配,等同于Matches(),主要是用于struct tag的range(min|max)

付録4型変換

func ToBoolean(str string) (bool, error)
func ToFloat(str string) (float64, error)
func ToInt(value interface{}) (res int64, err error)
func ToString(obj interface{}) string
func ToJSON(obj interface{}) (string, error)
func NormalizeEmail(str string) (string, error)    // 输出规范化的电子邮件格式

付録5.クリッピング処理、満たされ、トラバーサル

func Abs(value float64) float64 // 获得绝对值
func BlackList(str, chars string) string // 从字符串中移除指定字符
func CamelCaseToUnderscore(str string) string // 将驼峰拼写法转换为下划线分割写法,如MyFunc => my_func
func Count(array []interface{}, iterator ConditionIterator) int // 通过自定义ConditionIterator(实现了迭代器)来实现判断count
func Each(array []interface{}, iterator Iterator) // 通过自定义Iterator(实现了迭代器)来实现操作,不做任何返回,自行处理,比如打印一些东西
func Filter(array []interface{}, iterator ConditionIterator) []interface{} // 通过自定义ConditionIterator(实现了迭代器)来对[]interface{}的元素进行遍历处理
func Find(array []interface{}, iterator ConditionIterator) interface{} // 通过自定义ConditionIterator(实现了迭代器)来对[]interface{}的元素进行遍历查找,返回第一个找到的,若都没找到则返回nil
func GetLine(s string, index int) (string, error) // 从含多行的字符串中返回指定行内容(0为第一行),res, err := valid.GetLine("aa\nbb\ncc\n", 1) 返回bb
func GetLines(s string) []string // 将字符串的换行符去掉,返回由每一行组成的slice,原理就是strings.Split(s, "\n")
func LeftTrim(str, chars string) string // 若字符串最左边匹配了chars,则删除,如果chars为"",则删除前导符(空格、tab、换行符)
func Map(array []interface{}, iterator ResultIterator) []interface{}
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 RemoveTags(s string) string // RemoveTags remove all tags from HTML string
func ReplacePattern(str, pattern, replace string) string // 将正则匹配到的字符用指定字符替换
func Reverse(s string) string // 字符反转
func RightTrim(str, chars string) string // 若字符串最右边匹配了chars,则删除,如果chars为"",则删除前导符(空格、tab、换行符)
func SafeFileName(str string) string // 返回安全的文件名,裁剪掉空格等符号,转小写字母等
func Trim(str, chars string) string // 就是LeftTrim+RightTrim
func Truncate(str string, length int, ending string) string
func UnderscoreToCamelCase(s string) string // 将下划线分割写法转换为驼峰拼写法
func WhiteList(str, chars string) string // 从字符串中移除非指定字符

おすすめ

転載: blog.51cto.com/cyent/2438071