Go validator验证参数是否零值以及是否转达

[复制链接]
发表于 2025-12-11 09:39:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一:题目场景​

在Go中,当利用encoding/json包解码JSON数据到布局体时:


  • 如果前端未转达某个字段,validator会将该字段设置为其范例的零值。
  • 如果前端转达了该字段,而且是零值,validator同样会将其设置为相应的零值。
这意味着,仅凭字段的值,无法区分字段是未转达还是转达了零值。这在某些场景下大概导致题目。
二:办理方法​

利用指针与required标签,可以办理上面的题目。
(1)指针​

将字段设置为指针范例,那么:


  • 如果前端未转达该字段,validator会将指针设置为nil。
  • 如果前端有转达该字段,validator会将指针指向相应的值。
这意味着,利用指针,可以区分参数转达了或未转达。
(2)required标签​

required会验证字段值是否为零值,如果为零值,则验证不通过。
(3)联合利用​

对于接口中界说的字段参数,按照是否必传、是否可为零值,可分4种环境:

  • 必传,不可以为零值
    参数是必传的,而且不能是零值(好比购买数目)
    required
  • 必传,可为零值
    这种环境,参数是必传的,如果传的是零也要判断出来(好比传状态0或1)
    required + 指针
  • 非必传,不可以为零值
    这种环境,前端可以不传,但是传的参数不能是【零】(好比前端传筛选条件,要么不筛选,要么提供一个有效的值)
    非零条件
  • 非必传,可为零值
    这种环境,前端可以不传,但是传了【零】,我要能判断出来(好比把数目改为0,把形貌笔墨改为空)
    指针
三:总结

如果前端传的【零】有效,就利用指针。
必选参数,加required,没什么好说的。
四:示例

办理go gin框架 binding:"required"`无法吸收零值的题目
(1)未传指针

在用于绑定的布局体中,通常会利用 validator 库举行参数的校验,好比:
  1. type User struct {
  2.      Name   string `json:"name" binding:"required" example:"kkk"`
  3.      Age    int    `json:"age" binding:"required" example:"18"`
  4.      Status int    `json:"status" binding:"required" example:"1"`
  5. }
复制代码
我们规定前端转达的参数中,user、age、status 参数都为必填
然后在 Handler 函数中利用 ShouldBindJSON 绑定参数,如下:
  1. func handlerT(c *gin.Context) {
  2.      var user User
  3.      if err := c.ShouldBindJSON(&user); err != nil {
  4.          fmt.Println(err)
  5.          c.JSON(400, gin.H{"msg": "参数错误" + err.Error()})
  6.          return
  7.      }
  8. }
复制代码
测试题目
当 status 值为 0 的时间,参数校验就会不通过

(2)传指针

缘故因由是:Go 中会给布局体中没有赋值的字段赋予零值(int 范例默认 0、string 范例默认 "",等等),标签写成 require 时,如果转达零值,validator 校验的时间就会以为没有转达这个字段,进而报错
办理方法也很简单,既然缘故因由是由于字段的范例零值是 0,那选用默认值不是 0 的数据范例,而且也要是数值范例
以是,办理方法就是:把 int 范例改为 *int 范例,利用 int 的指针范例,零值为 nil,如许转达的时间就能乐成绑定
布局体改为:
  1. type User struct {
  2.      Name   string `json:"name" binding:"required" example:"kkk"`
  3.      Age    int    `json:"age" binding:"required" example:"18"`
  4.      Status *int   `json:"status" binding:"required" example:"1"`
  5. }
复制代码

测试


注意
可以看到,user.Status == 0 这一段报错了,由于 user.Status 是指针范例,不能直接与 int 范例比力,要想比力只能加上地点符 * ,大概再利用一个变量吸收由 *int 范例转换来的 int 范例

(3)小结

当遇到 validator 库无法校验零值时,把数据范例换为对应的指针范例即可正常吸收,但是在后续逻辑中,不能直接用这个指针范例的值举行通例运算,要么加上地点符 * 要么用中心变量吸收转换后的值
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表