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
有疑问加站长微信联系(非本文作者)