【GoLang】利用validator包实现服务端参数校验时自定义错误信息

在C/S架构下,服务端在校验请求参数时,若出现参数错误,要响应给客户端一个错误消息,通常我们会统一响应“参数错误”。在这里插入图片描述
在这里插入图片描述
但是,如果只是一味的提示参数错误,我并不知道具体是哪个参数错了呀!能不能有更详细,更细致的提示信息?例如(账号错误、密码为空、姓名不能包含数字),当然可以,下面我来教你如何利用validator包实现自定义参数错误信息。

validator包下载

validator是开源的第三方包,专门用于进行参数校验。我们先下载一下:

github.com/go-playground/validator/v10

打上结构体标签

validator包提供了结构体标签选项,我们可以为想要进行参数校验的字段打上标签,之后就会以此标签作为校验标准
在这里插入图片描述

进行参数校验

Struct方法会检验其参数s(假设参数s为结构体)是否符合结构体标签的标准(上文提到的validate标签)。若不符合标准,则将具体不符合的情况作为err返回。
在这里插入图片描述

现在我们模拟一遍请求参数错误时的场景

package main

import (
	"fmt"
	"github.com/go-playground/validator/v10"
)

type RegisterModel struct {
	Username string `validate:"required,numeric"`               // numeric 必须是数字
	Password string `validate:"required,alphanum"`              // alphanum 必须是数字字母组合
	Name     string `validate:"required"`                       // required 必须非空
	Age      int    `validate:"required,gte=0,lte=100,numeric"` // gte, lte 为最大最小值
	Gender   string `validate:"required,oneof=男 女"`             // oneof 必须为其中的某个值
}

func main() {
	// 模拟客户端发来的请求参数
	model := RegisterModel{
		Username: "中文中文",	// 故意让其不符合标准
		Password: "123哈哈哈",
		Name:     "",
	}

	// 用validator包进行校验
	validate := validator.New()	// 先new一个对象
	err := validate.Struct(model)	// 通过对象调用Struct方法
	if err != nil {
		fmt.Println(err)
	}
}

打印错误信息,可以发现其中包含了 不符合标准的字段 和 不符合标准的标签(下文将其统称为错误字段、错误标签)在这里插入图片描述

有了这些信息,就方便我们进行自定义参数信息了!但是仅有这些还不够,我们需要将这些信息各自提取到变量中。

将错误字段和错误标签提取出来

validator包里也给我们提供了方法:我们先将得到的err断言成validator.ValidationErrors,其本质是一个结构体切片,结构体中包含了错误字段和错误标签。接着我们遍历该结构体,即可拿到错误字段和错误标签。

		// 将err中包含的字段和标签提取出来
		if validationErrors, ok := err.(validator.ValidationErrors); ok {	// 将err断言
			for _, vErr := range validationErrors { // validationErrors 是一个结构体切片
				fmt.Println(vErr.StructField(), vErr.Tag())	// 打印得到的错误字段和错误标签
			}
		}

在这里插入图片描述

实战如下

package main

import (
	"fmt"
	"github.com/go-playground/validator/v10"
)

type RegisterModel struct {
	Username string `validate:"required,numeric"`               // numeric 必须是数字
	Password string `validate:"required,alphanum"`              // alphanum 必须是数字字母组合
	Name     string `validate:"required"`                       // required 必须非空
	Age      int    `validate:"required,gte=0,lte=100,numeric"` // gte, lte 为最大最小值
	Gender   string `validate:"required,oneof=男 女"`             // oneof 必须为其中的某个值
}

func main() {
	// 模拟客户端发来的请求参数
	model := RegisterModel{
		Username: "中文中文",
		Password: "123哈哈哈",
		Name:     "",
	}

	// 用validator包进行校验

	validate := validator.New()

	err := validate.Struct(model)
	if err != nil {
		fmt.Println(err)
		// 将err中包含的字段和标签提取出来
		if validationErrors, ok := err.(validator.ValidationErrors); ok {
			for _, vErr := range validationErrors { // validationErrors 是一个结构体切片
				vErr.StructField()
				vErr.Tag()
				fmt.Println(vErr.StructField(), vErr.Tag())
			}
		}
	}
}

在这里插入图片描述

现在我们有了错误字段和错误标签,我们就可以自定义参数错误信息了。

自定义参数错误信息

这里我用的方法是我自创的,比较土,主要是在map中通过错误字段、错误标签映射到自定义的信息。
首先声明两个map
声明的2个map
然后在遍历中通过map的映射关系获取到自定义信息。
在这里插入图片描述
实战:

package main

import (
	"fmt"
	"github.com/go-playground/validator/v10"
)

type RegisterModel struct {
	Username string `validate:"required,numeric"`               // numeric 必须是数字
	Password string `validate:"required,alphanum"`              // alphanum 必须是数字字母组合
	Name     string `validate:"required"`                       // required 必须非空
	Age      int    `validate:"required,gte=0,lte=100,numeric"` // gte, lte 为最大最小值
	Gender   string `validate:"required,oneof=男 女"`             // oneof 必须为其中的某个值
}

// 错误标签map
var tagMsg = map[string]string{
	"no-whitespace": "不能含有空格", // 键为结构体标签,值为自定义的错误信息
	"required":      "不能为空",
	"numeric":       "必须是数字",
	"alphanum":      "只能包含字母和数字",
	"oneof":         "错误",
	"lte":           "超出限定范围",
	"gte":           "超出限定范围",
}

// 错误字段map
var fieldMsg = map[string]string{
	"Username":   "账号", // 键为字段名,值为自定义的字段名信息
	"Password":   "密码",
	"Name":       "姓名",
	"Age":        "年龄",
	"Gender":     "性别",
	"Permission": "权限",
}

func main() {
	// 模拟客户端发来的请求参数
	model := RegisterModel{
		Username: "中文中文",
		Password: "123哈哈哈",
		Name:     "",
	}

	// 用validator包进行校验

	validate := validator.New()

	err := validate.Struct(model)
	if err != nil {
		fmt.Println(err)
		// 将err中包含的字段和标签提取出来
		if validationErrors, ok := err.(validator.ValidationErrors); ok {
			for _, vErr := range validationErrors { // validationErrors 是一个结构体切片
				fmt.Println(fieldMsg[vErr.StructField()] + tagMsg[vErr.Tag()])
			}
		}
	}
}

输出结果:在这里插入图片描述

至此,我们就用validator包实现自定义参数错误信息。
感谢浏览,如有不对欢迎指出。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习 vs 深度学习

目录 一、机器学习 1、实现原理 2、实施方法 二、深度学习 1、与机器学习的联系与区别 2、神经网络的历史发展 3、神经网络的基本概念 一、机器学习 1、实现原理 训练(归纳)和预测(演绎) 归纳: 从具体案例中抽象一般规律…

Unity git版本管理

创建仓库的时候添加了Unity的.gitignore模版,在这个时候就能自动过滤不需要的文件 打开git bash之后,步骤git版本管理-CSDN博客 如果报错,尝试重新进git 第一次传会耗时较长,之后的更新就很快了

【JWT】jwt实现HS、RS、ES、ED签名与验签

JWT 实现 HS、RS、ES 和 ED 签名与验签 签名方式算法密钥类型签名要点验签要点HSHMAC-SHA256对称密钥- 使用 crypto/hmac 和对称密钥生成 HMAC 签名- 将 header.payload 作为数据输入- 使用同一密钥重新计算 HMAC 签名- 比较计算结果与接收到的签名是否一致RSRSA-SHA256公钥 …

【Bug 记录】el-sub-menu 第一次进入默认不高亮

项目场景: 项目场景:el-sub-menu 第一次进入默认不高亮 问题描述 例如:sub-menu 的 index 后端默认传过来是 number,我们需要手动转为 string,否则会有警告,而且第一次进入 sub-menu 默认不高亮。 解决方…

LLM幻觉(Hallucination)缓解技术综述与展望

LLMs 中的幻觉问题(LLM 幻觉:现象剖析、影响与应对策略)对其可靠性与实用性构成了严重威胁。幻觉现象表现为模型生成的内容与事实严重不符,在医疗、金融、法律等对准确性要求极高的关键领域,可能引发误导性后果&#x…

挖掘机的市场现状和发展前景:全球增长潜力,重塑基础设施建设新篇章

引言:工程机械的心脏,挖掘机的崛起之路 在现代化建设的浪潮中,挖掘机作为工程机械领域的核心设备,正以其强大的作业能力和广泛的应用场景,成为推动全球基础设施建设不可或缺的力量。从高速公路到大型矿场,…

算法每日双题精讲 —— 二分查找(山脉数组的峰顶索引,寻找峰值)

🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟 别再犹豫了!快来订阅我们的算法每日双题精讲专栏,一起踏上算法学习的精彩之旅吧💪 在算法的…

Flutter_学习记录_基本组件的使用记录

1.TextWidge的常用属性 1.1TextAlign: 文本对齐属性 常用的样式有: TextAlign.center 居中TextAlign.left 左对齐TextAlign.right 有对齐 使用案例: body: Center(child: Text(开启 TextWidget 的旅程吧,珠珠, 开启 TextWidget 的旅程吧&a…

二叉树的存储(下)c++

链式存储 我们可以创建两个数组L[N]、r[N]&#xff0c;分别存储i 号结点的左右孩子的编号&#xff0c;这样就可以通过数组下标实现链式访问。 本质上还是孩子表示法&#xff0c;存储的是左右孩子的信息 #include <iostream>using namespace std;const int N 1e6 10; …

基于Docker的Kafka分布式集群

目录 1. 说明 2. 服务器规划 3. docker-compose文件 kafka{i}.yaml kafka-ui.yaml 4. kafka-ui配置集群监控 5. 参数表 6. 测试脚本 生产者-异步生产: AsyncKafkaProducer1.py 消费者-异步消费: AsyncKafkaConsumer1.py 7. 参考 1. 说明 创建一个本地开发环境所需的k…

Linux系统 C/C++编程基础——基于Qt的图形用户界面编程

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天周四了&#xff0c;距离除夕只有4天了&#xff0c;各位今年卫生都搞完了吗&#xff01;&#x1f606; 本文是接着昨天Linux 系统C/C编程的知识继续讲&#xff0c;基于Qt的图形用户界面编程概念及其命令&#xff0c;后续会不断…

C++11(二)

目录 左值引用与右值引用 左值引用 右值引用 右值与左值交叉引用 移动语义 移动构造 移动赋值 完美转发 本期我们将学习C11中比较重要的一个知识点------右值引用。 左值引用与右值引用 在学习左值引用和右值引用之前&#xff0c;我们得先知道什么是左值&#xff0…

【python】四帧差法实现运动目标检测

四帧差法是一种运动目标检测技术&#xff0c;它通过比较连续四帧图像之间的差异来检测运动物体。这种方法可以在一定的程度上提高检测的准确性。 目录 1 方案 2 实践 ① 代码 ② 效果图 1 方案 具体的步骤如下&#xff1a; ① 读取视频流&#xff1a;使用cv2.VideoCapture…

SpringBoot开发(二)Spring Boot项目构建、Bootstrap基础知识

1. Spring Boot项目构建 1.1. 简介 基于官方网站https://start.spring.io进行项目的创建. 1.1.1. 简介 Spring Boot是基于Spring4框架开发的全新框架&#xff0c;设计目的是简化搭建及开发过程&#xff0c;并不是对Spring功能上的增强&#xff0c;而是提供了一种快速使用Spr…

PMP–一、二、三模–分类–12.采购管理

文章目录 技巧十二、采购管理 一模12.采购管理--3.控制采购--输出--风险登记册--每个被选中的卖方都会带来特殊的风险。随着早期风险的过时以及新风险的出现&#xff0c;在项目执行期间对风险登记册进行变更。 供应商还未开始做&#xff0c;是一个风险&#xff0c;当做风险进行…

栈和队列(C语言)

目录 数据结构之栈 定义 实现方式 基本功能实现 1&#xff09;定义&#xff0c;初始化栈 2&#xff09;入栈 3&#xff09;出栈 4&#xff09;获得栈顶元素 5)获得栈中有效元素个数 6&#xff09;检测栈是否为空 7&#xff09;销毁栈 数据结构之队列 定义 实现方…

B站pwn教程笔记-1

因为没有垃圾处理机制&#xff0c;适合做编译&#xff0c;不会有堵塞 c语言市场占有率还是比较高的。 Windows根据后缀识别文件&#xff0c;linux根据文件头识别 55:16 编译过程 一步&#xff1a;直接gcc编译.c文件 这只是其中的一些步骤 gcc -S 转变为汇编。但其实这时候还…

jQuery小游戏

jQuery小游戏&#xff08;一&#xff09; 嘻嘻&#xff0c;今天我们来写个jquery小游戏吧 首先&#xff0c;我们准备一下写小游戏需要准备的佩饰&#xff0c;如果&#xff1a;图片、音乐、搞怪的小表情 这里我准备了一些游戏中需要涉及到的图片 游戏中使用到的方法 eval() 函…

Batch Normalization学习笔记

文章目录 一、为何引入 Batch Normalization二、具体步骤1、训练阶段2、预测阶段 三、关键代码实现四、补充五、参考文献 一、为何引入 Batch Normalization 现在主流的卷积神经网络几乎都使用了批量归一化&#xff08;Batch Normalization&#xff0c;BN&#xff09;1&#xf…

JavaSec系列 | 动态加载字节码

视频教程在我主页简介或专栏里 目录&#xff1a; 动态加载字节码 字节码 加载远程/本地文件 利用defineClass()直接加载字节码 利用TemplatesImpl加载字节码 动态加载字节码 字节码 Java字节码指的是JVM执行使用的一类指令&#xff0c;通常被存储在.class文件中。 加载远程…