分享
  1. 首页
  2. 文章

golang validators 对 Struct 的字段校验

LLL_小浪 · · 2660 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:LLL_小浪

查看原文:golang validators 对 Struct 的字段校验

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2660 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏