当前位置: 首页 > news >正文

gin框架使用系列之五——表单校验

  • 系列目录
    • 《gin框架使用系列之一——快速启动和url分组》
    • 《gin框架使用系列之二——uri占位符和占位符变量的获取》
    • 《gin框架使用系列之三——获取表单数据》
    • 《gin框架使用系列之四——json和protobuf的渲染》

一 、表单验证的基本理论

  在第三篇中,我们介绍了如何将form表单和json等数据转成结构体对象中的方法,当时在绑定的结构体中,其tag中就有“binding”的信息,这就是gin中表单验证的基础。为了详细了解表单验证,我们进一步了解以下表单绑定的知识。

1.1、若要将请求体绑定到结构体中,需要使用模型绑定,支持JSON、XML、YAML和标准表单的绑定,设置时需要在绑定的字段上设置tag,其只要有两套绑定方法

  • Must bind

    • 方法: Bind 、BindJSON、BindXML、BindQuery、BindYAML
    • 行为:这些方法底层使用MustBindWith方法,如果存在绑定错误,请求将被终止,响应代码会被设置成400
  • Should bind

    • 方法: ShouldBind、ShouldBindJSON、ShouldBindXML、ShouldBindQuery、ShouldBindYAML
    • 行为:底层使用ShouldBindWith方法,如果存在绑定错误,则返回go语言的错误形式,开发人员可以处理错误,请求不会被终止

1.2、Gin中使用 go-playground/validator来验证表单,详细文档

二、表单验证示例

我们以一个注册的接口的表单验证为例,示例表单验证的写法如下:

type SignUpParam struct {//  1<= age <= 130Age uint8 `json:"age" binding:"gte=1,lte=130"`// name,必须Name string `json:"name" binding:"required"`// email,必须且满足email格式Email string `json:"email" binding:"required,email"`// password,必须Password string `json:"password" binding:"required"`// re_password,必须,且要和password字段相同RePassword string `json:"re_password" binding:"required,eqfield=Password"`
}func main() {router := gin.Default()router.POST("/sign-up", func(c *gin.Context) {var param SignUpParamif err := c.ShouldBind(&param); err != nil {c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error(),})return}// TODO 业务逻辑c.JSON(http.StatusOK, "success")})router.Run() // listen and serve on 0.0.0.0:8080
}

在postman中调用接口,报错信息如下:
在这里插入图片描述

三、表单验证信息国际化

上面示例中我们可以看到表单验证信息的报错中,显示的不是很详细,而且暴露了go后台代码的数据,我们可以为其添加国际化信息。
下面是增加翻译器的方法


func InitTrans(locale string) (err error) {//修改gin框架中的validator引擎属性, 实现定制if v, ok := binding.Validator.Engine().(*validator.Validate); ok {//注册一个获取json的tag的自定义方法v.RegisterTagNameFunc(func(fld reflect.StructField) string {name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]if name == "-" {return ""}return name})zhT := zh.New() //中文翻译器enT := en.New() //英文翻译器//第一个参数是备用的语言环境,后面的参数是应该支持的语言环境uni := ut.New(enT, zhT, enT)trans, ok = uni.GetTranslator(locale)if !ok {return fmt.Errorf("uni.GetTranslator(%s)", locale)}switch locale {case "en":en_translations.RegisterDefaultTranslations(v, trans)case "zh":zh_translations.RegisterDefaultTranslations(v, trans)default:en_translations.RegisterDefaultTranslations(v, trans)}return}return
}

整体代码如下:

package mainimport ("fmt""net/http""reflect""strings""github.com/gin-gonic/gin""github.com/gin-gonic/gin/binding""github.com/go-playground/locales/en""github.com/go-playground/locales/zh"ut "github.com/go-playground/universal-translator""github.com/go-playground/validator/v10"en_translations "github.com/go-playground/validator/v10/translations/en"zh_translations "github.com/go-playground/validator/v10/translations/zh"
)type SignUpParam struct {//  1<= age <= 130Age uint8 `json:"age" binding:"gte=1,lte=130"`// name,必须Name string `json:"name" binding:"required"`// email,必须且满足email格式Email string `json:"email" binding:"required,email"`// password,必须Password string `json:"password" binding:"required"`// re_password,必须,且要和password字段相同RePassword string `json:"re_password" binding:"required,eqfield=Password"`
}// 定义一个全局的翻译器
var trans ut.Translatorfunc main() {//代码侵入性很强 中间件if err := InitTrans("zh"); err != nil {fmt.Println("初始化翻译器错误")return}router := gin.Default()router.POST("/sign-up", func(c *gin.Context) {var param SignUpParamif err := c.Bind(&param); err != nil {errs, ok := err.(validator.ValidationErrors)if !ok {c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error(),})return}// 检查使用自定义的转换器c.JSON(http.StatusBadRequest, gin.H{"msg": errs.Translate(trans),})return}// TODO 业务逻辑c.JSON(http.StatusOK, "success")})router.Run() // listen and serve on 0.0.0.0:8080
}
func InitTrans(locale string) (err error) {//修改gin框架中的validator引擎属性, 实现定制if v, ok := binding.Validator.Engine().(*validator.Validate); ok {//注册一个获取json的tag的自定义方法v.RegisterTagNameFunc(func(fld reflect.StructField) string {name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]if name == "-" {return ""}return name})zhT := zh.New() //中文翻译器enT := en.New() //英文翻译器//第一个参数是备用的语言环境,后面的参数是应该支持的语言环境uni := ut.New(enT, zhT, enT)trans, ok = uni.GetTranslator(locale)if !ok {return fmt.Errorf("uni.GetTranslator(%s)", locale)}switch locale {case "en":en_translations.RegisterDefaultTranslations(v, trans)case "zh":zh_translations.RegisterDefaultTranslations(v, trans)default:en_translations.RegisterDefaultTranslations(v, trans)}return}return
}

用postman输入错误信息如下:
在这里插入图片描述

输入全部正确信息如下:

在这里插入图片描述


后记
  个人总结,欢迎转载、评论、批评指正

相关文章:

gin框架使用系列之五——表单校验

系列目录 《gin框架使用系列之一——快速启动和url分组》《gin框架使用系列之二——uri占位符和占位符变量的获取》《gin框架使用系列之三——获取表单数据》《gin框架使用系列之四——json和protobuf的渲染》 一 、表单验证的基本理论 在第三篇中&#xff0c;我们介绍了如何…...

HackTheBox - Medium - Linux - Interface

Interface Interface 是一种中等难度的 Linux 机器&#xff0c;具有“DomPDF”API 端点&#xff0c;该端点通过将“CSS”注入处理后的数据而容易受到远程命令执行的影响。“DomPDF”可以被诱骗在其字体缓存中存储带有“PHP”文件扩展名的恶意字体&#xff0c;然后可以通过从其…...

C++ 字符串操作说明 续

一、strstr函数 extern char *strstr(char *str1, const char *str2); 1. strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是&#xff0c;则该函数返回str2在str1中首次出现的地址&#xff1b;否则&#xff0c;返回NULL。 2. str1: 被查找目标 string …...

[情商-7]:如何回答没有标准答案的两难问题

目录 前言&#xff1a; 一、用“逻辑推理思维”回答两难问题 二、用“情绪思维”回答两难问题 1.1 关注提问者提出问题背后的情绪状态和情绪/情感诉求 1.2 常见的常见的情绪和情感诉求 1.3 女性情感分析 1.4 理解女性情感的语言 1.5 如何通过语言理解女性的情绪需求 三…...

对偶问题的基本性质

写于&#xff1a;2024年1月3日晚 修改于&#xff1a; 原规划与对偶规划 原规划对偶规划 max ⁡ z C T X s.t. { A X ≤ b , 其中 X ( m ∗ 1 ) X ≥ 0 \begin{aligned} & \max \mathrm{z}\mathbf{C}^T \mathbf{X} \\ & \text { s.t. }\left\{\begin{array}{l}\mat…...

Google Chrome 现在会在后台扫描泄露的密码

谷歌表示&#xff0c;Chrome 安全检查功能将在后台运行&#xff0c;检查网络浏览器中保存的密码是否已被泄露。 如果桌面用户正在使用标记为危险的扩展程序&#xff08;从 Chrome Web Store 中删除&#xff09;、最新的 Chrome 版本&#xff0c;或者如果启用安全浏览来阻止 Go…...

【Matlab】PSO-BP 基于粒子群算法优化BP神经网络的数据时序预测(附代码)

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88689096 目录 【Matlab】BP 神经网络时序预测算法 【Matlab】CNN卷积神经网络时序预测算法 【Matlab】ELM极限学习机时序预测算法 【Matlab】基于遗传算法优化BP神经网络 (GA-BP)的数据时序预测 【Mat…...

Linux 485驱动通信异常

背景 前段时间接到一个项目&#xff0c;要求用主控用485和MCU通信。将代码调试好之后&#xff0c;验证没问题就发给测试了。测试测的也没问题。 但是&#xff0c;到设备量产时&#xff0c;发现有几台设备功能异常。将设备拿回来排查&#xff0c;发现是485通信有问题&#xff…...

mybatis配置与标签大全

文章目录 mybatis配置与标签大全mybatis的配置属性&#xff08;properties&#xff09;设置&#xff08;settings&#xff09;类型别名&#xff08;typeAliases&#xff09;类型处理器&#xff08;typeHandlers&#xff09;对象工厂&#xff08;objectFactory&#xff09;插件&…...

Mysql的基本用法(上)非常详细、快速上手

上篇结束了java基础&#xff0c;本篇主要对Mysql中的一些常用的方法进行了总结&#xff0c;主要对查询方法进行了讲解&#xff0c;包括重要的多表查询用到的内连接和外连接等&#xff0c;以下代码可以直接复制到可视化软件中&#xff0c;方便阅读以及练习&#xff1b; SELECT *…...

使用Vite创建React + TypeScript(node版本为16.17.0,含资源下载)

PC端 安装指令&#xff1a; npm create vitelatest react-ts-pro -- --template react-tsVite是一个框架无关的前端工具链&#xff0c;可以快速的生成一个React TS的开发环境&#xff0c;并且可以提供快速的开发体验说明&#xff1a; 1. npm create vitelatest固定写法&#…...

Springboot集成RabbitMq二

接上一篇&#xff1a;Springboot集成RabbitMq一-CSDN博客 1、搭建项目-消费者 与之前一样 2、创建配置类 package com.wym.rabbitmqconsumer.utils;import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.spring…...

机器学习笔记 - 基于Python的不平衡数据的欠采样技术

一、简述 随着从不同的来源生成和捕获大量数据。尽管信息量巨大,但它往往反映了现实世界现象的不平衡分布。数据不平衡的问题不仅仅是统计上的挑战,它对数据驱动模型的准确性和可靠性具有深远的影响。 以金融行业欺诈检测为例。尽管我们希望避免欺诈,因为其具有高度破坏性,…...

facebook广告的基础知识

Facebook广告是在Facebook、Instagram、Audience Network等与Facebook相关的SNS和服务上投放的广告。以下是关于Facebook广告的基础知识&#xff1a; 广告类型&#xff1a; 静态图片广告&#xff1a;主要通过Facebook的新闻提要投放的图片广告&#xff0c;可以张贴产品和服务…...

java常见面试题:什么是异常?Java中的异常有哪些分类?

异常是一个汉语词语&#xff0c;读音为y chng&#xff0c;指非正常的&#xff1b;不同于平常的&#xff1b;非常。在Java中&#xff0c;异常&#xff08;Exception&#xff09;是程序在运行过程中出现的不正常情况&#xff0c;例如除以零、数组越界等。异常分为两大类&#xff…...

类的加载顺序问题-demo展示

面试的的时候经常会被问到包含静态代码块、实例代码块和构造器等代码结构的加载顺序问题&#xff0c;下面借用一个面试题&#xff0c;回顾一下类的代码加载顺序。 public class AooTest {public static void main(String[] args) {AooTest.f1();}static AooTest test1 new Ao…...

[蓝桥杯2020国赛]答疑

答疑 题目描述 有 n 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。 老师可以安排答疑的顺序&#xff0c;同学们要依次进入老师办公室答疑。 一位同学答疑的过程如下&#xff1a; 首先进入办公室&#xff0c;编号为 i 的同学需要 si​ 毫秒的时间。然后同学问…...

【AIGC表情prompt】提示词练习技巧

表情类提示词练习技巧 医疗机器人&#xff0c;男人笑脸景深&#xff0c;数据&#xff0c;座标&#xff0c;12k,c4d渲染&#xff0c;高分辨率&#xff0c;,暖色调&#xff0c;高清对比 医疗机器人&#xff0c;男人微笑&#xff0c;景深&#xff0c;数据&#xff0c;座标&#xf…...

SpringBoot项目的三种创建方式

手动创建方式&#xff1a; ①&#xff1a;新建maven项目 ②&#xff1a;引入依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.10.RELEASE</version>&l…...

【docker实战】01 Linux上docker的安装

Docker CE是免费的Docker产品的新名称&#xff0c;Docker CE包含了完整的Docker平台&#xff0c;非常适合开发人员和运维团队构建容器APP。 Ubuntu 14.04/16.04&#xff08;使用 apt-get 进行安装&#xff09; # step 1: 安装必要的一些系统工具 sudo apt-get update sudo ap…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...

Python第七周作业

Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt&#xff0c;并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径&#xff0c;并创建logs目录&#xff08;若不存在&#xff09; 3.递归遍历目录data&#xff0c;输出所有.csv文件的路径…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用

摘要 神经影像技术对医学科学产生了深远的影响&#xff0c;推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下&#xff0c;基于神经血管耦合现象的多模态神经影像方法&#xff0c;通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里&#xff0c;本研…...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...