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

news2025/1/29 14:04:41

在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包实现自定义参数错误信息。
感谢浏览,如有不对欢迎指出。

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

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

相关文章

c#实现重启Explorer.exe并且启动某个命令

由于经常需要重启Explorer.exe 然后接着又需要马上启动一个命令行,于是干脆写一个程序,实现了此功能。 可以直接在运行中,或者在资源管理器中新建任务。 注意,下方的设置为应用程序,可以避免启动时出现黑框。 直接上代…

C语言自定义数据类型详解(一)——结构体类型(上)

什么是自定义数据类型呢?顾名思义,就是我们用户自己定义和设置的类型。 在C语言中,我们的自定义数据类型一共有三种,它们分别是:结构体(struct),枚举(enum),联合(union)。接下来,我…

绘制决策树尝试2 内含添加环境变量步骤

目录 step1 ai码 ai改 step2 下面就是环境配置问题 “ExecutableNotFound: failed to execute WindowsPath(‘dot’), make sure the Graphviz executables are on your systems’ PATH” dot -v愣是没有​编辑 graphviz安装指导 对于Windows用户: 对于Lin…

ChatGPT被曝存在爬虫漏洞,OpenAI未公开承认

OpenAI的ChatGPT爬虫似乎能够对任意网站发起分布式拒绝服务(DDoS)攻击,而OpenAI尚未承认这一漏洞。 本月,德国安全研究员Benjamin Flesch通过微软的GitHub分享了一篇文章,解释了如何通过向ChatGPT API发送单个HTTP请求…

【优选算法】10----无重复字符的最长子串

---------------------------------------begin--------------------------------------- 题目解析: 看到这一类题目,有没有那种一眼就感觉时要用到滑动窗口的感觉,铁子们? 讲解算法原理: 方法一: 暴力解法&#xff…

【模型】RNN模型详解

1. 模型架构 RNN(Recurrent Neural Network)是一种具有循环结构的神经网络,它能够处理序列数据。与传统的前馈神经网络不同,RNN通过将当前时刻的输出与前一时刻的状态(或隐藏层)作为输入传递到下一个时刻&…

开源鸿蒙开发者社区记录

lava鸿蒙社区可提问 Laval社区 开源鸿蒙项目 OpenHarmony 开源鸿蒙开发者论坛 OpenHarmony 开源鸿蒙开发者论坛

C语言中的|=代表啥意思?

在C语言中,| 是复合赋值运算符中的按位或赋值运算符。 其作用是将两个操作数按二进制位进行“或”运算,并将结果赋值给左操作数。例如,若有 x | y;,则等同于 x x | y;。其中,| 是按位或运算符,对两个操作数…

日志收集Day005

1.filebeat的input类型之filestream实战案例: 在7.16版本中已经弃用log类型,之后需要使用filebeat,与log不同,filebeat的message无需设置就是顶级字段 1.1简单使用: filebeat.inputs: - type: filestreamenabled: truepaths:- /tmp/myfilestream01.lo…

SVN客户端使用手册

目录 一、简介 二、SVN的安装与卸载 1. 安装(公司内部一般会提供安装包和汉化包,直接到公司内部网盘下载即可,如果找不到可以看下面的教程) 2. 查看SVN版本 ​编辑 3. SVN卸载 三、SVN的基本操作 1. 检出 2. 清除认证数据 3. 提交…

【深度学习基础】多层感知机 | 权重衰减

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…

怎么实现Redis的高可用?

大家好,我是锋哥。今天分享关于【请介绍一些常用的Java负载均衡算法,以实现高并发和高可用性?】面试题。希望对大家有帮助; 怎么实现Redis的高可用? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 要实现 Redis 的高…

“AI视觉贴装系统:智能贴装,精准无忧

嘿,朋友们!今天我要跟你们聊聊一个特别厉害的技术——AI视觉贴装系统。这可不是普通的贴装设备,它可是融合了人工智能、计算机视觉和自动化控制等前沿科技的“智能贴装大师”。有了它,那些繁琐、复杂的贴装工作变得轻松又精准。来…

SQL基础、函数、约束(MySQL第二期)

p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解 目录 SQL通用语法SQL数据类型SQL语句分类DDL数据库操作表操作-查询&创建典例表操作-修改字段表操作-改名&删除 DMLDML-插入(添加)数据DML-更新(修改)数据DML-删除数据 DQL基本…

hash路由、history路由

hash路由 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title><style>h…

unity 粒子系统实现碰撞检测(collision)且使粒子不受力

需求&#xff1a;通过碰撞检测的方式&#xff0c;获得粒子碰撞到的物体&#xff0c;并且碰撞之后&#xff0c;粒子的运动方向&#xff0c;旋转等物理性质都保持不变 为什么不用trigger&#xff1f;因为trigger虽然不会使粒子受力&#xff0c;但是在触发回调函数中&#xff0c;…

金融级分布式数据库如何优化?PawSQL发布OceanBase专项调优指南

前言 OceanBase数据库作为国产自主可控的分布式数据库&#xff0c;在金融、电商、政务等领域得到广泛应用&#xff0c;优化OceanBase数据库的查询性能变得愈发重要。PawSQL为OceanBase数据库提供了全方位的SQL性能优化支持&#xff0c;助力用户充分发挥OceanBase数据库的性能潜…

Anaconda安装及使用

文章目录 Anaconda安装关于PyTorch的安装和使用Frequently Asked Questions 在PyCharm中使用PyTorchapex库的安装 声明&#xff1a;以下内容均是根据个人经验总结&#xff0c;可能存在不合理之处&#xff0c;烦请指正。 Anaconda安装 打开Anaconda Prompt 输入&#xff1a;cond…

Prometheus+Grafana监控minio对象存储

1. 安装 MinIO 步骤 1&#xff1a;下载 MinIO 二进制文件 wget https://dl.min.io/server/minio/release/linux-amd64/miniochmod x miniosudo mv minio /usr/local/bin/ 步骤 2&#xff1a;创建数据目录 sudo mkdir -p /data/miniosudo chown -R $USER:$USER /data/minio …

使用Cline+deepseek实现VsCode自动化编程

不知道大家有没有听说过cursor这个工具&#xff0c;类似于AIVsCode的结合体&#xff0c;只要绑定chatgpt、claude等大模型API&#xff0c;就可以实现对话式自助编程&#xff0c;简单闲聊几句便可开发一个软件应用。 但cursor受限于外网&#xff0c;国内用户玩不了&#xff0c;…