golang validator 包的使用指北

news2024/11/24 2:53:39

看到 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:      "helloworld@qq.com",
      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 源码包以及官方文档,还是非常有意思的

感谢阅读,欢迎交流,点个赞,关注一波 再走吧

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~
可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/995352.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么要使用设计模式,以及使用设计模式的好处

在软件开发中,衡量软件质量只要包含如下指标: 正确性可维护性可读性可扩展性简洁性可测试性健壮性灵活性可复用性 然而,对于一些刚入行的新程序员来说,往往会注意不到上面这些问题,从而产生了一些让人头皮发麻的烂代…

用python实现基本数据结构【04/4】

说明 如果需要用到这些知识却没有掌握,则会让人感到沮丧,也可能导致面试被拒。无论是花几天时间“突击”,还是利用零碎的时间持续学习,在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢?列表、字典、集…

5分钟 将“.py”文件转为“.pyd”文件

代码: from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize import osfile_list os.listdir("./") extensions [] for file in file_list:if file.endswith(".py") and file !…

软件界面常见的布局窗口基本布局和名字

软件基本界面分布 下图是PS界面的各个功能块布局,(图片来源网络) 基本界面功能 常见的界面中,菜单栏和工具栏一般都是挨着的,属性窗口在右边,例如excel 程序编程软件界面中 一般比普通的软件多出来工…

linux-OpenSSL升级

1.安装编译所需的安装包 yum install -y gcc make perl zlib-devel 2.从 OpenSSL 官网下载(https://www.openssl.org/source/openssl-1.1.1v.tar.gz) 注:如果原先版本为1.x.x,升级时还是需要选择1.x.x 3. 编译安装 # 解压tar -xvf openssl-1.1.1v.tar…

flyway7.1.1适配人大金仓postgres版本

1、进入flyway github仓库下载flyway7.1.1版本源码,搜索7.1.1,下载地址为:https://github.com/flyway/flyway/releases 2、解压源码, 新建目录kingbase,将postgres目录文件拷贝进kingbase,修改下文件名&…

OpenCV(三十三):计算轮廓面积与轮廓长度

1.介绍轮廓面积与轮廓长度 轮廓面积(Contour Area)是指轮廓所包围的区域的总面积。通常情况下,轮廓面积的单位是像素的平方。 轮廓长度(Contour Length)又称周长(Perimeter),表示轮廓…

华为云云耀云服务器L实例评测|在Linux下部署Etherpad文档编辑器

华为云云耀云服务器L实例评测|在Linux下部署Etherpad文档编辑器 一、前言1.1 云耀云服务器L实例简介1.2 Etherpad简介 二、本次实践介绍2.1 本次实践简介2.2 本次环境规划 三、购买云耀云服务器L实例3.1 购买云耀云服务器L实例3.3 查看云耀云服务器L实例状态3.4 重置…

Pytorch3D多角度渲染.obj模型

3D理解在从自动驾驶汽车和自主机器人到虚拟现实和增强现实的众多应用中发挥着至关重要的作用。在过去的一年里,PyTorch3D已经成为一个越来越流行的开源框架,用于使用Python进行3D深度学习。值得庆幸的是,PyTorch3D 库背后的人员已经完成了实现…

【Spring Boot】分页查询

分页查询 分页查询是日常开发中比较常用的功能。MyBatis框架下也有很多插件实现分页功能,比如pageHelper。这是一款非常简单、易用的分页插件,能很好地集成在Spring Boot中。pageHelper是一款基于MyBatis的数据库分页插件,所以我们在使用它时…

【力扣每日一题】2023.9.10 课程表Ⅱ

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 今天的题目和昨天类似,不过今天要我们求出学习所有课程的先后顺序。 昨天只需要我们求出能否学习完所有课程,因此…

MIT6.828实验记录-Lab2

实验1完成了内核启动的相关操作,由实验1可知,首先BIOS(0xf0000~0x10000064KB)将Boot Loader加载到0x7c00~0x7dff(512B)处,Boot Loader代码执行后将内核代码的ELF文件读取到0x100000其…

静态工厂模式,抽象工厂模式,建造者模式

静态工厂模式 ublic class FruitFactory {public static Fruit getFruit(String name) {Fruit fnull;switch (name){case "APPLE":{fnew Apple();}case "BANANA":{fnew Banana();}default :{System.out.println("Unknown Fruit");}}return f;} …

基于Fomantic UI Web构建 个人导航站点网站源码 网站技术导航源码

BYR-Navi-master好看有个性的网站技术导航源码 该网站基于Fomantic UI Web框架构建,整个项目的设计和构建具有高度的配置和定制灵活性。 整体风格比较适合个人导航站点使用 搜索框输入关键词后,点击上方搜索引擎图标可跳转打开对应搜索引擎搜索结果&am…

UG二次开发 向量叉乘 UF_VEC3_cross

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介: UG二次开发 向量叉乘 UF_VEC3_cross,xyz三个向量已知2个求另外1个。 效果: 代码: #include "me.hpp"void ufusr(char* param, int* retcode, int paramLe…

通讯软件019——分分钟学会Prosys OPC UA Server配置

本文介绍如何配置Prosys OPC UA Simulation Server,通过本文可以对OPC UA的基本概念有所了解,掌握OPC UA的本质。更多通信资源请登录网信智汇(wangxinzhihui.com)。 1、启动OPC UA Server Prosys OPC UA Simulation Server启动后就处于运行状态。 2、配…

将两个Series序列的元素按指定条件整合Series.combine()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 把两个序列中各元素 将相同索引对应的值 按指定函数进行整合 得到整合后的结果序列 Series.combine() [太阳]选择题 关于以下代码的说法中错误的是? import pandas as pd a pd.Series([0,3],…

推荐云智推地推拉新系统源码/任务分销神器

源码类型: PHP源码 显示语言: 简体中文 运行环境:PHPMySQLTP 功能内容会员管理:总代,服务商,员工 三种会员;封号,编辑,删除;可开启或关闭总代权限和邀请下级…

Google Hacking搜索

Google Hacking概述 GoogleHacking基本用法逻辑或OR逻辑与And逻辑非NOT完整匹配 GoogleHacking高级用法sitefiletypeinurlintitleintext Google Hacking DataBaseGoogle Hacking概述 GoogleHacking:利用搜索引擎有争对性的搜索信息来对网络入侵的技术和行为。搜索引…

NLP(六十九)智能文档问答助手升级

本文在笔者之前研发的大模型智能文档问答项目中,开发更进一步,支持多种类型文档和URL链接,支持多种大模型接入,且使用更方便、高效。 项目介绍 在文章NLP(六十一)使用Baichuan-13B-Chat模型构建智能文档中…