go语言后端开发学习(三)——基于validator包实现接口校验

news2024/12/25 9:06:22

前言

在我们开发模块的时候,有一个问题是我们必须要去考虑的,它就是如何进行入参校验,在gin框架的博客中我就介绍过一些常见的参数校验,大家可以参考gin框架学习笔记(四) ——参数绑定与参数验证,而这个其实也不是能够完全应对我们在日常开发中的需要,而今天我们要介绍的就是如何基于validator这个第三方库来实现对接口入参的校验,话不多说,开始发车!

validator包的下载

go get github.com/go-playground/validator/v10

validator的使用

背景介绍

在讲解validator包的使用方式之前我们先来看一个应用场景:博主最近在写自己的博客网站,而博客网站中有一个问题,我们先来看一下表结构:

type User struct {
	gorm.Model
	Username string `gorm:"type:varchar(20)" json:"username"`
	Password string `gorm:"type:varchar(100)" json:"password"`
	Role     int    `gorm:"type:int;default:2" json:"role"`
}

在博客中我设置了两种角色管理员(role=1)普通用户(role=2),而这也造成了一个问题:我们在添加用户按照正常业务情况是不能直接在前台创建管理员,而这个就需要我们在后端进行参数校验了(备注:其实参数校验这件事前后端都是要做的,但是我们这里介绍主要是后端,就以后端视角来介绍了),而接下来我们以给这个用户模块做参数校验为例,来介绍一下我们如何来实现参数校验以及一些其他的相关操作。

为数据模型添加校验条件

type User struct {
	gorm.Model
	Username string `gorm:"type:varchar(20)" json:"username" validate:"required,min=4,max=12"`
	Password string `gorm:"type:varchar(100)" json:"password" validate:"required,min=6 max=20"`
	Role     int    `gorm:"type:int;default:2" json:"role" validate:"required,gte=2"`
}

如上我们利用validate字段指明了数据的验证规则

拓展bindingvalidate的区别:

"validate"通常用于描述数据的验证规则,用于确保输入的数据符合特定的格式、要求或约束。验证通常在
数据提交之前进行,以确保数据的完整性和准确性。

而"binding"通常用于描述数据的绑定规则,用于将用户界面元素与数据模型进行关联。数据绑定确保用户输
入的数据与数据模型的字段正确地同步,使用户界面的更改能够反映在数据模型中,或反之亦然。因此,
"validate"主要关注数据的验证和校验,而"binding"主要关注数据在用户界面元素和数据模型之间的绑定
和同步。

编写数据校验模块

我先示范一下数据消炎模块的书写,然后我再给大家具体讲解一下代码,首先我们来看一下最终我们所定义的User数据模型:

type User struct {
	gorm.Model
	Username string `gorm:"type:varchar(20)" json:"username" validate:"required,min=4,max=12" label:"用户名"`
	Password string `gorm:"type:varchar(100)" json:"password" validate:"required,min=6,max=20" label:"密码"`
	Role     int    `gorm:"type:int;default:2" json:"role" validate:"required,gte=2" label:"角色码"`
}

这里主要添加了两个标签:

  • validate:用来记录我们做入参验证的时候所做的限制条件
  • label:作为标记来返回标签值作为字段的名称

我们再来看校验模块的源代码:

package validator

import (
	"fmt"
	"gin_vue_blog/utils/errmsg"
	"github.com/go-playground/locales/zh_Hans_CN"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	"github.com/go-playground/validator/v10/translations/zh"
	"reflect"
)

func Validator(data any) (string, int) {
	validate := validator.New()
	uni := ut.New(zh_Hans_CN.New())
	trans, _ := uni.GetTranslator("zh_Hans_CN")
	err := zh.RegisterDefaultTranslations(validate, trans) // 注册翻译器
	if err != nil {
		fmt.Println("err:", err)
	}
	validate.RegisterTagNameFunc(func(field reflect.StructField) string {
		label := field.Tag.Get("label") // 获取label标签
		return label
	})
	err = validate.Struct(data)
	if err != nil {
		for _, err := range err.(validator.ValidationErrors) {
			return err.Translate(trans), errmsg.ERROR
		}
	}
	return "", errmsg.SUCCESS
}

我们可以来测试一下这段代码,效果如下:
在这里插入图片描述
我们可以看到我们成功实现了数据的校验功能,我们来看一下这一整个过程:

  1. 初始化valitor
	validate := validator.New()
  1. 编写中间件,实现国际化
    validator中其默认的错误信息是英文,一定程度上会影响我们阅读,我们可以尝试将其转换为其他语言,这里我选择转换为简体中文:
uni := ut.New(zh_Hans_CN.New())
	trans, _ := uni.GetTranslator("zh_Hans_CN")
	err := zh.RegisterDefaultTranslations(validate, trans) // 注册翻译器
	if err != nil {
		fmt.Println("err:", err)
	}
  1. 进行数据校验并返回错误消息
    err = validate.Struct(data)
    if err != nil {
    	for _, err := range err.(validator.ValidationErrors) {
    		return err.Translate(trans), errmsg.ERROR
    	}
    }
    return "", errmsg.SUCCESS
    }
    

就这样我们就实现了一个通用的数据校验模块了。

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

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

相关文章

MYSQL 索引下推 45讲

刘老师群里,看到一位小友 问<MYSQL 45讲>林晓斌的回答 大意是一个组合索引 (a,b,c) 条件 a > 5 and a <10 and b123, 这样的情况下是如何? 林老师给的回答是 A>5 ,然后下推B123 小友 问 "为什么不是先 进行范围查询,然后在索引下推 b123?" 然后就…

python数据分析-Matplotlib绘图实例以及金融数据分析应用

通过学习扩展库matplotlib及背后的理论知识进行数据分析和可视化&#xff0c;重点以案例分析为主&#xff0c;通过实际案例演示相关理论和Python语言的应用。 读取文件countries-aggregated.csv数据&#xff0c;其中Date&#xff1a;日期, Country&#xff1a;国家, Confirmed…

格式化后硬盘数据能恢复吗?硬盘数据恢复这样做!

硬盘是电脑中必备的数据存储设备&#xff0c;另外还有移动硬盘。移动硬盘存储空间非常大、性价比高、便于携带&#xff0c;给我们带来和很多便利。但是和其他存储设备一样&#xff0c;各种硬盘也会出现各种问题&#xff0c;比如常见的格式化硬盘导致数据丢失的问题。 怎么样恢复…

【Linux系统化学习】网络层——IP协议

目录 IP协议 协议头格式 两个问题 网段划分 IP地址的分类 CIDR网段划分&#xff08;无分类编址&#xff09; 特殊的IP地址 IP地址的数量限制 私有IP地址和公网IP地址 路由 路由表的查询 IP协议 应用层、运输层上两层协议我们只考虑的是通信的双方对应层&#xff0c;…

MQ解决的问题

系统中MQ能解决哪些问题&#xff1f; 1.不同语言的程序使用MQ通信 2.分布式&#xff0c;微服务&#xff0c;之间的通信&#xff0c;实现服务质检解耦 3.高并发实现销峰作用 4.实现异步&#xff0c;提高用户体验。

Java的自动装箱和自动拆箱

自动装箱和拆箱在Java开发中的应用与注意事项 在Java开发中&#xff0c;自动装箱&#xff08;Autoboxing&#xff09;和自动拆箱&#xff08;Unboxing&#xff09;是指基本数据类型与其对应的包装类之间的自动转换。这些特性可以使代码更加简洁和易读&#xff0c;但在实际项目…

类和对象的学习总结(一)

面向对象和面向过程编程初步认识 C语言是面向过程的&#xff0c;关注过程&#xff08;分析求解问题的步骤&#xff09; 例如&#xff1a;外卖&#xff0c;关注点菜&#xff0c;接单&#xff0c;送单等 C是面向对象的&#xff0c;关注对象&#xff0c;把一件事拆分成不同的对象&…

机器学习笔记——支持向量机

支持向量机 参数模型对分布需要假设&#xff08;这也是与非参数模型的区别之一&#xff09;间隔最大化&#xff0c;形式转化为凸二次规划问题 最大化间隔 间隔最大化是意思&#xff1a;对训练集有着充分大的确信度来分类训练数据&#xff0c;最难以分的点也有足够大的信度将…

-31-()

在终端运行时消除输入空格对程序的影响可以使用{在scanf后加“getchar()”或者在scanf&#xff08;“空格%d”,&a&#xff09;} 按位与和移位操作符只能用于整数且都要转位二进制后进行相应操作 不创建临时变量&#xff0c;实现两个数的交换&#xff1a;1——使用加减法&…

插卡式仪器模块:数据记录模块(插卡式)

• 32 位分辨率 • 250 KSPS 采样率 • 可以同时并且连续地记录两个通道的电压输入 • 实时上传原始数据至 PC 端 通道22输入阻抗电压22 kΩ10 MΩ电流0.2 Ω输入范围电压 250 mV 4.5 V电流1.5 A耦合DCDC带宽450 Hz385 HzADC 分辨率32 Bits24 Bits采样率10 kSPS250 kSPS测量…

【最新鸿蒙应用开发】——类Web开发范式1——生命周期

兼容JS的类Web开发范式 类Web命令式开发的生命周期 1. 应用生命周期 1.1. app.js 每个应用可以在app.js自定义应用级生命周期的实现逻辑&#xff0c;包括&#xff1a; onCreate&#xff1a;在应用生成时被调用的生命周期函数。 onDestroy&#xff1a;在应用销毁时被调用的生…

高德地图简单实现点标,和区域绘制

高德地图开发文档:https://lbs.amap.com/api/javascript-api/guide/abc/quickstart 百度搜索高德地图开发平台 注册高德地图开发账号 在应用管理中 我的应用中 添加一个Key 点击提交 进入高德地图开发文档:https://lbs.amap.com/api/javascript-api/guide/abc/quickstart …

详解FedProx:FedAvg的改进版 Federated optimization in heterogeneous networks

FedProx&#xff1a;2020 FedAvg的改进 论文&#xff1a;《Federated Optimization in Heterogeneous Networks》 引用量&#xff1a;4445 源码地址&#xff1a; 官方实现&#xff08;tensorflow&#xff09;https://github.com/litian96/FedProx 几个pytorch实现&#xff1a;…

【激光雷达】

激光雷达 机械式360扫描雷达半固态激光雷达二维扫描一维扫描 固态激光雷达OPA固态激光雷达&#xff08; 光学相控阵技术&#xff09;Flash激光雷达 FMCW 激光雷达 激光雷达技术在近几年可以说是蓬勃发展&#xff0c;新能源汽车的大量使用&#xff0c;给雷达技术的发展提供了肥沃…

C++系统编程篇——linux编译器 gcc/g++(链接动静态库)

linux编译器-gcc/g &#xff08;1&#xff09;g安装&#xff08;gcc一般自带&#xff0c;g需要下载&#xff09; sudo yum install -y gcc-c g --version gcc用于编译C语言代码&#xff0c;g用于编译C代码 &#xff08;2&#xff09;程序翻译过程 选项“-o”是指目标文件…

Python的else子句7个妙用,原来还能这样用,整挺好!

## 1、条件语句else基础 &#x1f504; 1.1 简单else的常规操作 在Python中&#xff0c;else子句通常跟在if或一系列if-elif之后&#xff0c;提供一个“否则”的情况处理路径。如果前面的所有条件都不满足 &#xff0c;程序就会执行这里的代码块。例如 &#xff0c;检查一个数…

目标检测(R-CNN)系列(Pytorch 26)

一 R-CNN 除了之前描述的单发多框检测之外&#xff0c;区域卷积神经网络&#xff08;region‐based CNN或regions with CNN features&#xff0c; R‐CNN&#xff09;(Girshick et al., 2014)也是将深度模型应用于目标检测的开创性工作之一。下面介绍R‐CNN及其一 系列改进方法…

【JavaEE】Spring Boot MyBatis详解(一)

一.MyBatis的基本概念与相关配置. 1.基本概念 MyBatis是一款优秀的持久层框架&#xff0c;用于简化JDBC的开发。MyBatis本是Apache的一个开源项目iBatis&#xff0c;2010年这个项目由apache迁移到了google code&#xff0c;并且改名为MyBatis. 2013年11月迁移到Github.持久层…

吴恩达2022机器学习专项课程C2W3:2.25 理解方差和偏差(诊断方差偏差正则化偏差方案)

目录 引言名词替代影响模型偏差和方差的因素1.多项式阶数2.正则化参数 判断是否有高偏差或高方差1.方法一&#xff1a;建立性能基准水平2.方法二&#xff1a;建立学习曲线 总结 引言 机器学习系统开发的典型流程是从一个想法开始&#xff0c;然后训练模型。初次训练的结果通常…

SpringSecurity入门(四)

18、权限管理/授权 18.1、针对url配置 配置SecurityConfig package com.wanqi.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.bu…