首页 > 其他分享 >golang validator 检验工具的使用指北

golang validator 检验工具的使用指北

时间:2023-10-22 17:13:03浏览次数:31  
标签:指北 string 约束 golang 标识 validator validate 参数值

golang validator 包的使用指北 原创 阿兵云原生 阿兵云原生 2023-09-10 09:27 发表于广东 看到 validator 咱们第一反应会想起啥?见名知意我就可以知道他是一个验证器,如果用过 gin web 框架的同学,自然是用过 gin 里面的 validator,只不过 gin 中使用的关键字是 binding 去做标识   开门见山 Validator 实际上是一个验证工具,属于 golang 的第三方包,这个包中使用了各种反射技巧来提供了各种校验和约束数据的方式方法,非常实用,常用的有这些:   基本的字段长度,大小,范围的约束   len:约束参数长度 eq:数值等于参数值 max:数值小于等于参数值 min:数值大于等于参数值 ne:不等于参数值 gt:大于参数值,gte:大于等于参数值 lt:小于参数值, lte:小于等于参数值 oneof:只能是枚举值中的一个,这些值必须是数值或字符串,以空格分隔,如果字符串中有空格,则使用单引号包围。例如:oneof=changsha beijing haerbing 是否必选,是否跳过,是否忽略   **-**:跳过该字段 | :使用多个约束,只需要满足其中一个,例如:xxx| xxx required:必选约束,不能为默认值 omitempty:如果字段未设置,则忽略它 各种格式约束如   email url ip、ipv4、ipv6 uuid datetime json file , 参数必须是一个合法的文件路径 常用的大概有上述这些,我们也不需要去背,只需要知道如何去使用,以及咱们需要处理数据校验的时候,能够想到 validator 库就行了,实在记不起来看官方文档或者看本篇文章的例子就可以了,这个是官网:   validator package - github.com/go-playground/validator/v10 - Go Packages   使用 使用 validator 工具, 自然是为了提高我们的开发效率以及让我们写出来的内容更加优雅和健壮   如果我们自己每一个字段都显示的去校验是否符合我们预期,那么代码大概率会很臃肿,来一个简单的 demo,举个栗子   package main   import (    "fmt"    "github.com/go-playground/validator/v10" )   type Data struct {    City string `validate:"min=8,max=15"`    Name string `validate:"min=6,max=10"`    Addr string `validate:"url"`    Age int `validate:"gte=18,lte=100"`    Tall int `validate:"required"`    IpAddr string `validate:"ipv4"`    Email string `validate:"email"`    Content string `validate:"json"`    CreateTime string `validate:"datetime=2006-01-02"`    NewPwd string `validate:"min=8"`    RePwd string `validate:"eqfield=NewPwd"` }   func main() {    // 示例 , 基本使用介绍    validate := validator.New()      demo1 := Data{       City: "changsha11111111111111",       Name: "xiaozhu",       Addr: "xxxxxxxxx",       Age: 25,       Tall: 185,       IpAddr: "xxxxxxxxxxx",       Email: "[email protected]",       Content: "{"name":"xiaozhu"}",       CreateTime: "xxxxx2006-03-02",       NewPwd: "12345",       RePwd: "123456789xxxxx",    }      err := validate.Struct(demo1)    if err == nil {       fmt.Println("params check success")       return    }      invalid, ok := err.(*validator.InvalidValidationError)    if ok {       fmt.Println("param invalid : ", invalid)       return    }      valiErrs := err.(validator.ValidationErrors)      for _, valiErr := range valiErrs {       fmt.Println(valiErr)    } } 此处我们可以看到我们在 Data 数据结构中,对其成员进行了不同的约束,相信通过 xdm 看到 Data 结构中的 validate 标识后面的约束,就知道响应字段的约束是啥意思了   例如   Age int `validate:"gte=18,lte=100"`   约束 Age 这个字段,需要满足 大于等于 18 ,小于等于 100 的范围   RePwd string `validate:"eqfield=NewPwd"`   RePwd 字段,需要和 NewPwd 字段相等 ,这个是用 eqfield 做标识的   关于 xxfield 的跨字段约束的相关标识可以查看官网的此处   这里是 valiator 能支持的所有类型,从字段内容,网络方面,字符串,数据结构,比较的字符,其他的标识   图片 另外关于邮箱约束的:   Email string `validate:"email"`   Email 字段,必须是 email 格式的,才能够检验通过   如上,每一个字段,如果需要校验的,校验失败,我们也可以全部打印出来   目前在 validator 中,处理错误信息,分为 2 种错误的情况:   InvalidValidationError 咱们将我们的 err 转换成 InvalidValidationError ,表示输入参数错误   ValidationErrors:字段违反约束,错误信息如下 咱们将我们的 err 转换成 ValidationErrors,这是一个切片,所以咱们可以遍历输出,这个是表示不符合约束字符的有错误原因   图片 validator.ValidationErrors 是一个 FieldError 类型的切片   type ValidationErrors []FieldError   FieldError 中包含了关于 error 的全部信息,我们可以调用 FieldError 里面的成员方法进行输出即可   type FieldError interface {    Tag() string    ActualTag() string    Namespace() string    StructNamespace() string    Field() string    StructField() string    Value() interface{}    Param() string    Kind() reflect.Kind    Type() reflect.Type    Translate(ut ut.Translator) string    Error() string } 关于其他标识的使用就不过多赘述了,使用方式都大同小异,咱们可以参考上述的 demo 即可   自定义约束 当然,如果认为官方提供的支持的标识还不能满足我们的要求,那么我们也是可以自定义咱们的标识的,例如,咱们要定义的标识是 happyhead ,含义就是,咱们定义的字符串,必须是以 happy 开头的,否则就校验不通过   此时咱们就需要使用到 validator 包中的 RegisterValidation 方法,再按照这个方法,提供一个校验实际参数的回调函数即可:   图片 我们就可以这样来写   图片 查看实际效果如下:   demo1 validate failed : Key: 'RegisterFormat.Name' Error:Field validation for 'Name' failed on the 'happyhead' tag demo2 validate success ... 至此,咱们将 validator 包中的特殊约束,格式约束,错误处理,范围约束,字符串约束,以及自定义约束都简单过了一下,这些东西不需要朗读和背诵,只需要咱们知道有他,需要的时候,能够找到,能够迅速使用起来即可   当然,如果想研究他的实现原理的,可以好好看看 validator 源码包以及官方文档,还是非常有意思的   感谢阅读,欢迎交流,点个赞,关注一波 再走吧   欢迎点赞,关注,收藏 朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力   图片 好了,本次就到这里   技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。   我是阿兵云原生,欢迎点赞关注收藏,下次见~       阅读 395   阿兵云原生 ​ 喜欢此内容的人还喜欢 Go 语言切片扩容规则是扩容2倍?1.25倍?到底几倍  我看过的号 阿兵云原生 不喜欢   Go语言与redis队列实现复杂的守护进程管理和错误处理机制?  我关注的号 Go语言圈 不喜欢   在Golang中玩转依赖注入-dig篇  凉凉的知识库 不喜欢     人划线    

标签:指北,string,约束,golang,标识,validator,validate,参数值
From: https://www.cnblogs.com/cheyunhua/p/17780695.html

相关文章

  • Golang logrus用法
    packagexlogimport( "bufio" "fmt" "github.com/sirupsen/logrus"rotatelogs"github.com/lestrrat-go/file-rotatelogs""github.com/rifflock/lfshook" "os" "time")typeConf......
  • Golang sync包中errgroup的使用详解
    WaitGroup主要用于控制任务组下的并发子任务。它的具体做法就是,子任务goroutine执行前通过Add方法添加任务数目,子任务goroutine结束时调用Done标记已完成任务数,主任务goroutine通过Wait方法等待所有的任务完成后才能执行后续逻辑packagemainimport("ne......
  • golang之xorm简单使用
    gogetgithub.com/go-xorm/xormpackagemainimport("fmt"_"github.com/go-sql-driver/mysql""github.com/go-xorm/xorm")typePointInfostruct{Idint64`xorm:"pkautoincr"`Product......
  • Systemd集成Golang二进制程序
    首先新建Service,名称叫做server-apivim/lib/systemd/system/server-api.service[Unit]Description=serverapi[Service]Type=simpleRestart=alwaysRestartSec=5sExecStart=/root/go/mainWorkingDirectory=/root/go/[Install]WantedBy=multi-user.targetExecStart......
  • Golang泛型的简单使用
    packagemainimport"fmt"//MyInt~表示不仅支持int8,还支持int8的衍生类型int8A和int8BtypeMyIntinterface{ int|~int8|int16|int32|int64}funcgetMaxNum[TMyInt](a,bT)T{ ifa>b{ returna } returnb}//结构体typeAgeTinterface{......
  • golang 实现协程池
    import( "fmt" "sync" "time")typeTaskfunc()typeThreadPoolstruct{ workerCountint taskQueuechanTask wgsync.WaitGroup}funcNewThreadPool(workerCount,maxTaskNumint)*ThreadPool{ pool:=&......
  • golang常见用法
    结构体数组与接口数组转换如果想把[]struct转为[]interface,我们发现直接赋值会报错。理论上interface可以转换任何数据,为什么结构体数组不可以呢?这是因为interface的设计导致的,如果能理解interface的底层实现,就能很清楚知道如何转换了。如图所示,与C++的虚函数类似,interface保......
  • golang生成uuid
    1,借助linux系统命令/usr/bin/uuidgen1.1代码packagemainimport("fmt""log""os/exec")funcmain(){out,err:=exec.Command("uuidgen").Output()iferr!=nil{log.Fatal(err)}fmt.......
  • fastjson JSONValidator 的使用记录
    在api的对接过程中,对方api总是会返回一些意想不到的格式回来,虽然你们已经约定好了使用json的方式返回!! 在调用一个api接口的时候结果就像薛定谔的猫是一个不确定的形态. 按照我之前的操作逻辑1判断结果空if(StringUtils.isEmpty(result)){return"结果空";}2......
  • 【转】dive into golang database/sql(1)
    转,原文:https://www.jianshu.com/p/3b0b3a4c83da ---------------数据库操作是一个应用必不可少的部分,但是我们很多时候对golang的sql包仅仅是会用,这是不够的。每一条语句的执行,它的背后到底发生了什么。各式各样对sql包的封装,是不是有必要的,有没有做无用功?这是gotodataba......