Go-Gin中优雅的实现参数校验,自定义错误消息提示

问题描述

在参数校验的时候我们一般会基于"github.com/go-playground/validator/v10"这个库给结构体加标签实现校验参数,当参数校验错误的时候,他的提示一般是英文的,怎么自定义参数错误提示呢?跟着我一步步来

注册校验器

package initializeimport ("ToDoList/global""ToDoList/model/request""ToDoList/util/validate""github.com/gin-gonic/gin/binding""github.com/go-playground/locales/zh"ut "github.com/go-playground/universal-translator"v10 "github.com/go-playground/validator/v10"zhTranslations "github.com/go-playground/validator/v10/translations/zh"
)func RegisterValidator[T interface{}](fn v10.StructLevelFunc, model T) {translator := zh.New()universalTransator := ut.New(translator, translator)global.GVA_TRANS, _ = universalTransator.GetTranslator("zh")if v, ok := binding.Validator.Engine().(*v10.Validate); ok {v.RegisterStructValidation(fn, model)_ = zhTranslations.RegisterDefaultTranslations(v, global.GVA_TRANS)}}type _Validator struct{}func (receiver _Validator) InitValidator() {RegisterValidator[request.Login](validate.UserLoginValidate.Validation, request.Login{})
}var Validator = new(_Validator)func (receiver *ginEngine) InitEngine() *gin.Engine {r := gin.Default()// 这里进行注册校验器!!Validator.InitValidator()return r
}

定义接口

我们定义一个接口规范,利于代码维护

package validateimport "github.com/go-playground/validator/v10"type Validation interface {CreateValidate() validator.StructLevelFunc
}

定义具体参数校验的方法

ReportError函数第四个参数Param将作为错误时消息提示。

package validateimport ("ToDoList/model/request""github.com/go-playground/validator/v10""reflect"
)type userLoginValidate struct{}func (receiver userLoginValidate) CreateValidate() validator.StructLevelFunc {return func(sl validator.StructLevel) {user := sl.Current().Interface().(request.Login)StructNotEmpty(sl, user, []string{})if !VerifyPassword(8, 16, user.Password) {sl.ReportError(reflect.ValueOf(user.Password), "", "", "", "密码要出现数字、大写字母、小写字母、特殊字符(.@$!%*#_~?&^),至少包含其中2种且长度在8-16之间")}}
}var UserLoginValidate = new(userLoginValidate)

定义公共函数

1.定义一个翻译的函数

func CustomErrMessage(err error) string {var result stringerrors := err.(validator.ValidationErrors)for _, err := range errors {if err.Param() != "" {result += err.Param() + ","}}return result
}

2.判断结构体字段是否为空

// 结构体字段判断是否为空
func StructNotEmpty(sl validator.StructLevel, st interface{}, omitKeys []string) {t := reflect.TypeOf(st)if t.Kind() == reflect.Ptr {t = t.Elem()}if t.Kind() != reflect.Struct {fmt.Println("必须传入结构体才能判断是否字段为空")return}v := reflect.ValueOf(st) //获取reflect.Type类for i := 0; i < v.NumField(); i++ {if !slices.Contains(omitKeys, t.Field(i).Name) {label := t.Field(i).Tag.Get("label")value := v.Field(i).Interface().(string)if len(value) == 0 {sl.ReportError(t.Field(i), "", "", "", fmt.Sprintf("%s不能为空", label))}}}
}

结构体标签

label标签是结构体字段的中文翻译,以便于当结构体字段为空时StructNotEmpty函数可以进行翻译。

type Login struct {Username  string `json:"username" binding:"required,min=4,max=16" label:"用户名"` // 用户名Password  string `json:"password" binding:"required,min=8,max=16" label:"密码"`  // 密码Captcha   string `json:"captcha" binding:"required" label:"验证码"`               // 验证码CaptchaId string `json:"captchaId" binding:"required" label:"验证码ID"`           // 验证码ID
}

返回结果

func (receiver *userApi) Login(c *gin.Context) {// 1.绑定用户表单数据var loginForm request.Login// 2.检验用户登录表单if err := c.ShouldBindJSON(&loginForm); err != nil {response.Response.FailWithMessage(validate.CustomErrMessage(err), c)return}
}

结果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

  1. 先在Gin中注册验证器
  2. 定义校验函数并通过sl validator.StructLevel调用sl.ReportError传入param参数作为自定义错误
  3. 然后绑定结构体 var loginForm request.Login if err := c.ShouldBindJSON(&loginForm);
  4. 当绑定失败的时候把err传给CustomErrMessage函数CustomErrMessage函数,将会把param的值作为错误结果
  5. 然后将CustomErrMessage函数返回结果给客户端即可

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

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

相关文章

OpenAI 宣布, ChatGPT 网页端无需注册就能立即使用(2024年4月1日)

今天&#xff0c;OpenAI宣布&#xff0c;为了让更多人轻松体验人工智能的强大功能&#xff0c;现在无需注册账户即可立即使用 ChatGPT。这一变化是他们使命的核心部分&#xff0c;即让像 ChatGPT 这样的工具广泛可用&#xff0c;让世界各地的人们都能享受到 AI 带来的好处。 网…

PostgreSQL的学习心得和知识总结(一百三十五)|深入理解PostgreSQL数据库之查找 PostgreSQL C 代码中的内存泄漏

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

【苍穹外卖】SkyApplication类启动报错

报的这个错 The PoM for com.sky:sky-common:jar:1.0-SNAPSHoT is missing, no dependency information available Maven里重新install一下就好

01-​JVM学习记录-类加载器

一、类加载器子系统 1. 作用-运输工具&#xff08;快递员&#xff09; 负责从文件系统或者网络中加载Class文件&#xff08;DNA元数据模板&#xff09;&#xff0c;Class文件开头有特定标识&#xff0c;魔术&#xff0c;咖啡杯壁&#xff08;class文件存于本地硬盘&#xff0c…

Java 设计模式系列:备忘录模式

简介 备忘录模式是一种软件设计模式&#xff0c;用于在不破坏封闭的前提下捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以方便地回到一个特定…

js动态替换字符串中所有匹配到的片段(replace + RegExp实现)

把字符串中匹配到的所有’A’替换成’哈’ <script>var text A12A34A56A789Avar result text.replace(new RegExp(A, g), 哈)console.log(result)//哈12哈34哈56哈789哈 </script>

版本排序,(如果 版本 是 1,1a,1.1a, 2, 2c , 1c , 1.2a, 3 , 5b , 5)进行排序

如果 版本 是 1&#xff0c;1a&#xff0c;1.1a&#xff0c; 2&#xff0c; 2c &#xff0c; 1c &#xff0c; 1.2a&#xff0c; 3 &#xff0c; 5b &#xff0c; 5 对上面的进行排序 利用 VersionComparator 导入依赖 <dependency><groupId>cn.hutool</groupId…

微信小程序开发学习笔记——4.8【小案例】初识wx.request获取网络请求并渲染至页面

>>跟着b站up主“咸虾米_”学习微信小程序开发中&#xff0c;把学习记录存到这方便后续查找。 课程连接&#xff1a;4.8.【小案例】初识wx.request获取网络请求并渲染至页面_哔哩哔哩_bilibili up主提供的网络请求常用接口&#xff1a; 随机猫咪&#xff0c;用来获取一些…

【Kotlin】委托模式

1 委托模式简介 委托模式的类图结构如下。 对应的 Kotlin 代码如下。 fun main() {var baseImpl BaseImpl()var baseWrapper BaseWrapper(baseImpl)baseWrapper.myFun1() // 打印: BaseImpl, myFun1baseWrapper.myFun2() // 打印: BaseImpl, myFun2 }interface Base {fun my…

非关系型数据库(缓存数据库)redis的基础认知与安装

目录 一.关系型数据库和非关系型数据库 关系型数据库 非关系型数据库 关系数据库与非关系型数据库的区别 ①非关系数据 关系型数据库 非关系型数据库产生背景 数据存储流向 非关系型数据库 关系数据库 二.redis的简介 1.概念 2.Redis 具有以下几个优点: 3.Redi…

Nginx请求upstream timed out 错误时通常会尝试重新请求上游服务器(504 Gateway Timeout)

重新记录一下这个重复的nginx请求的问题&#xff1a; 背景 一个导出报表任务&#xff0c;下载报表时&#xff0c;发生了导出超时&#xff1a;504 Gateway Timeout的错误。 504 Gateway Timeout的原因如下&#xff1a; Nginx配置问题&#xff1a;检查您的Nginx配置是否正确。…

测斜仪在边坡安全监测中的重要作用

边坡作为土木工程和地质工程领域中常见的结构形式&#xff0c;其稳定性直接关系到工程安全以及人民生命财产的安全。因此&#xff0c;对边坡进行精确、及时的监测是至关重要的。在众多边坡监测仪器中&#xff0c;测斜仪以其独特的优势在边坡安全监测中发挥着重要的作用。 测斜仪…

uniapp:小程序腾讯地图程序文件qqmap-wx-jssdk.js 文件一直找不到无法导入

先看问题&#xff1a; 在使用腾讯地图api时无法导入到qqmap-wx-jssdk.js文件 解决方法&#xff1a;1、打开qqmap-wx-jssdk.js最后一行 然后导入&#xff1a;这里是我的路径位置&#xff0c;可以根据自己的路径位置进行更改导入 最后在生命周期函数中输出&#xff1a; 运行效果…

vivado 高级编程功能1

适用于 7 系列、 UltraScale 和 UltraScale FPGA 和 MPSoC 的回读和验证 为 7 系列器件生成已加密文件和已经过身份验证的文件 注释 &#xff1a; 如需获取其它信息 &#xff0c; 请参阅《使用加密确保 7 系列 FPGA 比特流的安全》 ( XAPP1239 ) 。 要生成加密比特流…

设计模式之代理模式解析(下)

4&#xff09;远程代理介绍 远程代理(Remote Proxy) 使客户端程序可以访问在远程主机上的对象&#xff0c;远程代理对象承担了大部分的网络通信工作&#xff0c;并负责对远程业务方法的调用。 5&#xff09;虚拟代理介绍 1.概述 虚拟代理(Virtual Proxy) 对于一些占用系统资…

Kong基于QPS、IP限流

Rate Limiting限流插件 https://docs.konghq.com/hub/kong-inc/rate-limiting/ 它可以针对consumer ,credential ,ip ,service,path,header 等多种维度来进行限流.流量控制的精准度也有多种方式可以参考,比如可以做到秒级,分钟级,小时级等限流控制. 基于IP限流 源码地址&…

零基础入门多媒体音频(7)-AAOS audio

概览 Android Automotive OS (AAOS) 是基于核心的 Android 音频堆栈打造&#xff0c;以支持用作车辆信息娱乐系统。AAOS 负责实现信息娱乐声音&#xff08;即媒体、导航和通讯&#xff09;&#xff0c;但不直接负责具有严格可用性和时间要求的铃声和警告。 虽然 AAOS 提供了信号…

【Python】 使用Apache Tika和Python实现zip、csv、xls等多格式文件文本内容提取

时间的电影 结局才知道 原来大人已没有童谣 最后的叮咛 最后的拥抱 我们红着眼笑 我们都要把自己照顾好 好到遗憾无法打扰 好好的生活 好好的变老 好好假装我 已经把你忘掉 &#x1f3b5; 五月天《好好》 在进行数据分析、搜索引擎优化或任何需要处理大量…

路由器拨号失败解决方法

目录 一、遇到问题 二、测试 三、解决方法 &#xff08;一&#xff09;路由器先单插wan口设置 &#xff08;二&#xff09;mac地址替换 &#xff08;三&#xff09;更改路由器DNS 一、遇到问题 1 .在光猫使用桥接模式&#xff0c;由路由器进行拨号的时候&#xff0c;出现…

定时推送任务 Apache HttpClient/okhttp3

定时推送任务 需求 需要定时推送我方的数据到对方那边 方法1 Apache HttpClient 此方法指定推送过去的信息转为utf-8格式的json字符串 Scheduled(initialDelay 1000 * 120, fixedDelay 1000 * 60 * 5) public void diseaseInterface() {String lockKey "lock:dise…