Gin框架系列之数据校验


一、基本使用

在前面的文章中说明了数据绑定,就是将传递的参数绑定到结构体上,避免一个个的通过方法去获取,那么又该如何对传递的参数值进行校验呢?

可以在结构体上打上标签:

type LoginInfo struct {
    UserName string `form:"username" json:"username" binding:"required"`
    PassWord string `form:"password" json:"password" binding:"required"`
}

如果前端提交的是form数据,则会进行form标签的校验;如果提交的是json数据,则会进行json标签的的校验。

前端:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<form action="/do_index" method="post">
    用户名:<input type="text" name="username"> <br>
    密  码:<input type="password" name="password"> <br>
    <input type="submit">
form>
body>
html>

后端:

package main

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

type LoginInfo struct {
    UserName string `form:"username" json:"username" binding:"required"`
    PassWord string `form:"password" json:"password" binding:"required"`
}

func Index(ctx *gin.Context) {
    ctx.HTML(http.StatusOK, "index.html", nil)
}

func DoIndex(ctx *gin.Context) {
    var loginInfo LoginInfo
    err := ctx.ShouldBind(&loginInfo)
    if err != nil {
        fmt.Println(err)
        ctx.JSON(400, gin.H{
            "msg":  "fail",
            "code": 400,
        })
    }

    ctx.JSON(200, gin.H{
        "msg":  "success",
        "code": 200,
    })
}

func main() {
    router := gin.Default()

    router.LoadHTMLGlob("template/*")

    router.GET("/index", Index)
    router.POST("/do_index", DoIndex)

    router.Run(":8080")
}

二、验证器

1、什么是验证器

type LoginInfo struct {
    UserName string `form:"username" json:"username" binding:"required"`
    PassWord string `form:"password" json:"password" binding:"required"`
}

在上面的UserName和PassWord字段的标签中通过binding进行绑定不同的校验规则,binding后面的就是验证器,可以拥有多个,不同之间使用逗号分隔。如:

type LoginInfo struct {
    UserName string `form:"username" json:"username" binding:"required,min=5,max=10"` // 表示该字段不能为空,并且最小长度为5,最大长度为10

}

2、常用验证器

  • required: 必填字段,如:binding:"required"
  • min 最小长度,如:binding:"min=5"
  • max 最大长度,如:binding:"max=10"
  • len 长度,如:binding:"len=6"
  • eq 等于,如:binding:"eq=3"
  • ne 不等于,如:binding:"ne=12"
  • gt 大于,如:binding:"gt=10"
  • gte 大于等于,如:binding:"gte=10"
  • lt 小于,如:binding:"lt=10"
  • lte 小于等于,如:binding:"lte=10"
  • eqfield 等于其他字段的值,如:PassWord string `binding:"eqfield=ConfirmPassword"`
  • nefield 不等于其他字段的值
  • - 忽略字段,如:binding:"-"
  • | 或,如:binding:"rgb|rgba"

更多参考:https://pkg.go.dev/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags

三、自定义验证器 

 1、安装依赖

go get "github.com/go-playground/validator"

2、定义验证器

package handler

import "github.com/go-playground/validator"

var CustomValid validator.Func = func(fl validator.FieldLevel) bool {

    data := fl.Field().Interface().(string)

    if len(data) > 3 {
        return false
    } else {
        return true
    }
}

3、注册验证器

在路由匹配之前进行注册:

func main() {

    router := gin.Default()

    if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
        v.RegisterValidation("len_valid", handler.CustomValid)
    }

    router.LoadHTMLGlob("template/*")

    // 数据校验
    router.GET("/valid_index", ValidIndex)
    router.POST("/do_valid_index", DoValidIndex)

    router.Run(":8080")

}

4、使用验证器

type LoginInfo struct {
    UserName string `form:"username" json:"username" binding:"len_valid"`
    PassWord string `form:"password" json:"password" binding:"len_valid"`
}

更多参考:https://gin-gonic.com/zh-cn/docs/examples/custom-validators/