问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Go语言中 validation 库不能校验零值问题

创作时间:
作者:
@小白创作中心

Go语言中 validation 库不能校验零值问题

引用
CSDN
1.
https://blog.csdn.net/Shoulen/article/details/140917259

在使用Go语言的Gin框架进行Web开发时,经常会遇到参数校验的问题。本文将介绍在使用validator库进行参数校验时遇到的一个常见问题:当字段值为零值时,validator无法正确校验。通过一个具体的代码示例,我们将展示这个问题的产生原因,并提供一个简单有效的解决方案。

问题描述

在使用Gin框架处理前后端数据传递时,通常会使用ShouldBindJSON方法将前端传来的JSON格式数据绑定到结构体中。为了确保数据的完整性,我们会在结构体中使用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"`
}

我们规定前端传递的参数中,nameagestatus参数都为必填。然后在Handler函数中使用ShouldBindJSON绑定参数:

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

完整代码如下:

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
)

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"`
}

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

func main() {
    r := gin.Default()
    r.POST("/user", handlerT)
    // 监听
    err := r.Run(":9090")
    if err != nil {
        panic(err.Error())
    }
}

使用Postman调试接口时发现,当status值为0时,参数校验就会不通过:

解决方法

这个问题的原因在于Go语言会给结构体中没有赋值的字段赋予零值(例如,int类型的零值是0,string类型的零值是空字符串)。当标签写成required时,如果传递零值,validator校验时会认为没有传递这个字段,从而报错。

解决方法很简单:将int类型改为*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"`
}

再次使用Postman调试,可以看到参数已经成功绑定:

但是,使用指针类型后,后续处理中需要特别注意。例如,如果需要判断user.Status是否为0,不能直接使用user.Status == 0,因为user.Status是指针类型,需要使用*user.Status == 0或者先将指针类型转换为int类型再进行比较。

总结

当遇到validator库无法校验零值的问题时,可以将数据类型改为对应的指针类型。但是,在后续逻辑处理中,不能直接使用这个指针类型的值进行常规运算,需要通过解引用或类型转换来处理。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号