Go validator验证参数是否零值以及是否传递

ops/2024/12/12 16:48:39/

gin框架-bindingrequired无法接收零值的问题">一:问题场景​

在Go中,当使用encoding/json包解码JSON数据到结构体时:

  • 如果前端未传递某个字段,validator会将该字段设置为其类型的零值。
  • 如果前端传递了该字段,并且是零值,validator同样会将其设置为相应的零值。

这意味着,仅凭字段的值,无法区分字段是未传递还是传递了零值。这在某些场景下可能导致问题。

二:解决方法​

使用指针required标签,可以解决上面的问题。

(1)指针​

将字段设置为指针类型,那么:

  • 如果前端未传递该字段,validator会将指针设置为nil
  • 如果前端有传递该字段,validator会将指针指向相应的值。

这意味着,使用指针,可以区分参数传递了未传递

(2)required标签​

required会验证字段值是否为零值,如果为零值,则验证不通过。

(3)结合使用​

对于接口中定义的字段参数,按照是否必传、是否可为零值,可分4种情况:

  1. 必传,不可以为零值

    参数是必传的,并且不能是零值(比如购买数量)

    required

  2. 必传,可为零值

    这种情况,参数是必传的,如果传的是零也要判断出来(比如传状态0或1)

    required + 指针

  3. 非必传,不可以为零值

    这种情况,前端可以不传,但是传的参数不能是【零】(比如前端传筛选条件,要么不筛选,要么提供一个有效的值)

    非零条件

  4. 非必传,可为零值

    这种情况,前端可以不传,但是传了【零】,我要能判断出来(比如把数量改为0,把描述文字改为空)

    指针

三:总结

如果前端传的【零】有效,就使用指针

必选参数,加required,没什么好说的。

四:示例

gin框架-bindingrequired无法接收零值的问题">解决go gin框架 binding:"required"`无法接收零值的问题

(1)未传指针

在用于绑定的结构体中,通常会使用 validator 库进行参数的校验,比如:

type User struct {Name   string `json:"name" binding:"required" example:"kkk"`Age    int    `json:"age" binding:"required" example:"18"`Status int    `json:"status" binding:"required" example:"1"`}

我们规定前端传递的参数中,user、age、status 参数都为必填

然后在 Handler 函数中使用 ShouldBindJSON 绑定参数,如下:

func handlerT(c *gin.Context) {var user Userif err := c.ShouldBindJSON(&user); err != nil {fmt.Println(err)c.JSON(400, gin.H{"msg": "参数错误" + err.Error()})return}}

测试问题

当 status 值为 0 的时候,参数校验就会不通过

(2)传指针

原因是:Go 中会给结构体中没有赋值的字段赋予零值(int 类型默认 0、string 类型默认 "",等等),标签写成 require 时,如果传递零值,validator 校验的时候就会认为没有传递这个字段,进而报错

解决方法也很简单,既然原因是因为字段的类型零值是 0,那选用默认值不是 0 的数据类型,而且也要是数值类型

所以,解决方法就是:把 int 类型改为 *int 类型,使用 int 的指针类型,零值为 nil,这样传递的时候就能成功绑定

结构体改为:

type User struct {Name   string `json:"name" binding:"required" example:"kkk"`Age    int    `json:"age" binding:"required" example:"18"`Status *int   `json:"status" binding:"required" example:"1"`
}

测试

注意

可以看到,user.Status == 0 这一段报错了,因为 user.Status 是指针类型,不能直接与 int 类型比较,要想比较只能加上地址符 * ,或者再使用一个变量接收由 *int 类型转换来的 int 类型

(3)小结

当遇到 validator 库无法校验零值时,把数据类型换为对应的指针类型即可正常接收,但是在后续逻辑中,不能直接用这个指针类型的值进行常规运算,要么加上地址符 * 要么用中间变量接收转换后的值


http://www.ppmy.cn/ops/141288.html

相关文章

el-table手动触发懒加载

二次修改了一下,确保点击某一单元格格元素触发 // 隐藏懒加载箭头后手动触发懒加载 expandRows(scope){scope.row.isExpanded !scope.row.isExpanded // 切换展开状态let isExpanded scope.row.isExpandedconst { table: { toggleRowExpansion, store }} this.$r…

Ionic 8.4 简介

Ionic 是一个用于开发混合移动应用、渐进式Web应用(PWA)以及桌面应用的开源框架。它结合了 Angular、React 或 Vue.js 等现代前端框架与 Cordova/PhoneGap 的力量,允许开发者使用 Web 技术(HTML, CSS, JavaScript)构建…

MacBook Pro触控板按不动解决方法

MacBook Pro突然触控板就不好使了。指针可以正常移动,但是触控板按不动了,想到之前风扇狂转的问题通过重置 SMC解决的,于是尝试重置 SMC,竟然搞定了! 大家有类似的问题可以尝试重置 SMC (以下问题也可以尝…

解决Vue项目中npm install卡住问题的详细指南

解决Vue项目中npm install卡住问题的详细指南 引言 在开发Vue项目时,我们经常会遇到npm install命令卡住的问题,特别是在构建依赖树时。本文将分享一些实用的解决方案,帮助您快速解决这一常见问题。 问题描述 在执行npm install时&#xf…

「嵌入式系统设计与实现」书评:学习一个STM32的案例

本文最早发表于电子发烧友论坛:【新提醒】【「嵌入式系统设计与实现」阅读体验】 学习一个STM32的案例 - 发烧友官方/活动 - 电子技术论坛 - 广受欢迎的专业电子论坛!https://bbs.elecfans.com/jishu_2467617_1_1.html 感谢电子发烧友论坛和电子工业出版社的赠书。 …

蓝桥杯软件赛系列---lesson1

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 我们今天会再开一个系列,那就是蓝桥杯系列,我们会从最基础的开始讲起,大家想要备战明年蓝桥杯的,让我们一起加油。 工具安装 DevC…

Ubuntu安装grafana

需求背景:管理服务器,并在线预警,通知 需求目的: 及时获取服务器状态 技能要求: 1、ubuntu 2、grafana 3、prometheus 4、node 步骤: 一、grafana安装 1、准备系统环境,配置号网络 2、…

第二章、数值

无符号和有符号整数 显式转换时,底层二进制值不变,只是应用层解释不一样隐式转换时,基本所有运算符都是把其中的有符号转为无符号,底层二进制值不变扩展时,无符号高位补0, 有符号高位补符号位,举个3bit的i…