boss: 这小子还不会使用validator库进行数据校验,开了~~~

2022-07-07 15:50:47 浏览数 (1)

前言

哈喽,大家好,我是asong。这是我的第十篇原创文章。这周在公司做项目,在做API部分开发时,需要对请求参数的校验,防止用户的恶意请求。例如日期格式,用户年龄,性别等必须是正常的值,不能随意设置。最开始在做这一部分的时候,我采用老方法,自己编写参数检验方法,统一进行参数验证。后来在同事CR的时候,说GIN有更好的参数检验方法,gin框架使用github.com/go-playground/validator进行参数校验,我们只需要在定义结构体时使用bindingvalidatetag标识相关校验规则,就可以进行参数校验了,很方便。相信也有很多小伙伴不知道这个功能,今天就来介绍一下这部分。

快速安装

使用之前,我们先要获取validator这个库。

代码语言:javascript复制
# 第一次安装使用如下命令
$ go get github.com/go-playground/validator/v10
# 项目中引入包
import "github.com/go-playground/validator/v10"

简单示例

安装还是很简单的,下面我先来一个官方样例,看看是怎么使用的,然后展开分析。

代码语言:javascript复制
package main

import (
 "fmt"
 "net/http"

 "github.com/gin-gonic/gin"
)

type RegisterRequest struct {
 Username string `json:"username" binding:"required"`
 Nickname string `json:"nickname" binding:"required"`
 Email    string `json:"email" binding:"required,email"`
 Password string `json:"password" binding:"required"`
 Age      uint8  `json:"age" binding:"gte=1,lte=120"`
}

func main() {

 router := gin.Default()

 router.POST("register", Register)

 router.Run(":9999")
}

func Register(c *gin.Context) {
 var r RegisterRequest
 err := c.ShouldBindJSON(&r)
 if err != nil {
  fmt.Println("register failed")
  c.JSON(http.StatusOK, gin.H{"msg": err.Error()})
  return
 }
 //验证 存储操作省略.....
 fmt.Println("register success")
 c.JSON(http.StatusOK, "successful")
}

  • 测试
代码语言:javascript复制
curl --location --request POST 'http://localhost:9999/register' 
--header 'Content-Type: application/json' 
--data-raw '{
    "username": "asong",
    "nickname": "golang梦工厂",
    "email": "7418.com",
    "password": "123",
    "age": 140
}'
  • 返回结果
代码语言:javascript复制
{
    "msg": "Key: 'RegisterRequest.Email' Error:Field validation for 'Email' failed on the 'email' tagnKey: 'RegisterRequest.Age' Error:Field validation for 'Age' failed on the 'lte' tag"
}

看这个输出结果,我们可以看到validator的检验生效了,email字段不是一个合法邮箱,age字段超过了最大限制。我们只在结构体中添加tag就解决了这个问题,是不是很方便,下面我们就来学习一下具体使用。

validator库

gin框架是使用validator.v10这个库来进行参数验证的,所以我们先来看看这个库的使用。

先安装这个库:

代码语言:javascript复制
$ go get github.com/go-playground/validator/v10

然后先写一个简单的示例:

代码语言:javascript复制
package main

import (
 "fmt"

 "github.com/go-playground/validator/v10"
)

type User struct {
 Username string `validate:"min=6,max=10"`
 Age      uint8  `validate:"gte=1,lte=10"`
 Sex      string `validate:"oneof=female male"`
}

func main() {
 validate := validator.New()

 user1 := User{Username: "asong", Age: 11, Sex: "null"}
 err := validate.Struct(user1)
 if err != nil {
  fmt.Println(err)
 }

 user2 := User{Username: "asong111", Age: 8, Sex: "male"}
 err = validate.Struct(user2)
 if err != nil {
  fmt.Println(err)
 }

}

我们在结构体定义validator标签的tag,使用validator.New()创建一个验证器,这个验证器可以指定选项、添加自定义约束,然后在调用他的Struct()方法来验证各种结构对象的字段是否符合定义的约束。

上面的例子,我们在User结构体中,有三个字段:

  • Name:通过min和max来进行约束,Name的字符串长度为[6,10]之间。
  • Age:通过gte和lte对年轻的范围进行约束,age的大小大于1,小于10。
  • Sex:通过oneof对值进行约束,只能是所列举的值,oneof列举出性别为男士

    0 人点赞