美文网首页golang
Go - validators 对 Struct 的字段校验

Go - validators 对 Struct 的字段校验

作者: 灵魂深灵 | 来源:发表于2019-08-02 15:55 被阅读0次
    1、需求:

    有时我们需要对接收到的struct字段内容进行验证,比如:

    type Student struct {
        Uid   int64
        Name  string
        Age   int64
        Sex   string
        Email string
    }
    
    我们需要对结构体内的字段进行验证合法性:
    • Uid的值在某一个范围内
    • Name值的长度在某一个范围内
    • Sex的值符合男或女
    • Email格式正确等等
    2、安装:

    go get github.com/smokezl/govalidators

    3、先来个简单例子,通过golang的structTag来配置验证器:
    type Class struct {
        Cid       int64  `validate:"required||integer=10000,_"`
        Cname     string `validate:"required||string=1,5||unique"`
        BeginTime string `validate:"required||datetime=H:i"`
    }
    
    type Student struct {
        Uid          int64    `validate:"required||integer=10000,_"`
        Name         string   `validate:"required||string=1,5"`
        Age          int64    `validate:"required||integer=10,30"`
        Sex          string   `validate:"required||in=male,female"`
        Email        string   `validate:"email||user||vm"`
        PersonalPage string   `validate:"url"`
        Hobby        []string `validate:"array=_,2||unique||in=swimming,running,drawing"`
        CreateTime   string   `validate:"datetime"`
        Class        []Class  `validate:"array=1,3"`
    }
    
    • required 判断字段对应的值是否是对应类型的零值
    • integer 表示字段类型是否是整数类型,如果integer后边不接=?,?,那么表示只判断是否是整数类型,如果后边接=?,?,那么有四种写法:
      (1). integer=10 表示字段值 = 10
      (2). integer=_ ,10 表示字段值 <= 10,字段值最小值为字段对应类型的最小值(比如字段对应类型为int8,那么最小为−128),最大值为10
      (3). integer=10, _ 表示字段值 >= 10,字段值最小值为10,最大值为字段对应类型的最大值(比如字段对应类型为int8,那么最大为127)
      (4). integer=1,20 表示字段值 >=1 并且 <= 20
    • array、string 同 integer,array=?,? 表示元素个数范围,string=?,? 表示字符串长度范围
    • email 表示字段值是否是合法的email地址
    • url 表示字段值是否是合法的url地址
    • in 表示字段值在in指定的值中,比如 Hobby 字段中,in=swimming,running,drawing,表示 Hobby 字段的值,只能是swimming,running,drawing中的一个或多个
    • datetime 表示字段值符合日期类型,如果datetime后边不接=?,那么默认为Y-m-d H:i:s,否则验证器会按照指定格式判断,比如 datetime=Y-m、datetime=Y/m/d H:i:s等,可以是Y m d H i s 的随意拼接
    • unique 表示字段值唯一,比如 Hobby 字段的 unique,表示 Hobby 字段值唯一,Class 中,Cname 字段的 unique,表示 Cname 字段值唯一。
    package main
    
    import (
        "fmt"
        "github.com/smokezl/govalidators"
    )
    
    //把上面的两个Struct复制到此处
    
    func goValidators() {
        validator := govalidators.New()
        student := &Student{
            Uid:          1234567,
            Name:         "张三1111",
            Age:          31,
            Sex:          "male1",
            Email:        "@qq.com",
            PersonalPage: "www.abcd.com",
            Hobby:        []string{"swimming", "singing"},
            CreateTime:   "2018-03-03 05:60:00",
            Class: []Class{
                Class{
                    Cid:       12345678,
                    Cname:     "语文",
                    BeginTime: "13:00",
                },
                Class{
                    Cid:       22345678,
                    Cname:     "数学",
                    BeginTime: "13:00",
                },
                Class{
                    Cid:       32345678,
                    Cname:     "数学",
                    BeginTime: "13:60",
                },
            },
        }
        errList := validator.Validate(student)
        if errList != nil {
            for _, err := range errList {
                fmt.Println("err:", err)
            }
        }
        
    }
    
    func main() {
        goValidators()
    }
    

    执行结果:

    err: Name should be betwween 1 and 5 chars long
    err: Age should be betwween 10 and 30
    err: Sex is not in params [male female]
    err: Email is not a email address
    err: validator user not exist
    err: validator vm not exist
    err: PersonalPage is not a url
    err: Hobby is not in params [swimming running drawing]
    err: CreateTime is not a date time
    err: Cname is not unique
    err: BeginTime is not a date time

    有时,我们不需要将错误全部收集到,而是只要其中一个有错,可以用 LazyValidate 方法:

    err := validator.LazyValidate(student)
    if err != nil {
        fmt.Println("err:", err)
    }
    

    执行结果:

    err: Name should be betwween 1 and 5 chars long

    如果我们想把刚才的报错信息,都改为中文,那么就可以对每个验证器错误 msg 进行自定义:

    //自定义msg错误信息
        validator := govalidators.New()
        validator.SetValidators(map[string]interface{}{
            "string": &govalidators.StringValidator{
                Range: govalidators.Range{
                    RangeEMsg: map[string]string{
                        "between": "[name] 长度必须在 [min] 和 [max] 之间",
                    },
                },
            },
            "integer": &govalidators.IntegerValidator{
                Range: govalidators.Range{
                    RangeEMsg: map[string]string{
                        "between": "[name] 的值必须在 [min] 和 [max] 之间",
                    },
                },
            },
            "in": &govalidators.InValidator{
                EMsg: "[name] 的值必须为 [args] 中的一个",
            },
            "email": &govalidators.EmailValidator{
                EMsg: "[name] 不是一个有效的email地址",
            },
            "url": &govalidators.UrlValidator{
                EMsg: "[name] 不是一个有效的url地址",
            },
            "datetime": &govalidators.DateTimeValidator{
                EMsg: "[name] 不是一个有效的日期",
            },
            "unique": &govalidators.UniqueValidator{
                EMsg: "[name] 不是唯一的",
            },
        })
        errList := validator.Validate(student)
        if errList != nil {
            for _, err := range errList {
                fmt.Println("err:", err)
            }
        }
    

    执行结果:

    err: Name 长度必须在 1 和 5 之间
    err: Age 的值必须在 10 和 30 之间
    err: Sex 的值必须为 [male female] 中的一个
    err: Email 不是一个有效的email地址
    err: validator user not exist
    err: validator vm not exist
    err: PersonalPage 不是一个有效的url地址
    err: Hobby 的值必须为 [swimming running drawing] 中的一个
    err: CreateTime 不是一个有效的日期
    err: Cname 不是唯一的
    err: BeginTime 不是一个有效的日期

    在校验Struct时是根据下面链接中的文章做的,其中还有一些扩展目前还没有测。
    更多详情点击:https://www.jianshu.com/p/64757be312a4

    相关文章

      网友评论

        本文标题:Go - validators 对 Struct 的字段校验

        本文链接:https://www.haomeiwen.com/subject/ljmldctx.html