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>Title</title>
</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/ 

四、beego驗證器 

(一)簡單使用

 1、安裝依賴

go get github.com/astaxie/beego/validation

2、結構體中使用

  • 驗證函數寫在 "valid" tag 的標簽里
  • 各個驗證規則之間用分號 ";" 分隔,分號后面可以有空格
  • 參數用括號 "()" 括起來,多個參數之間用逗號 "," 分開,逗號后面可以有空格
  • 正則函數(Match)的匹配模式用兩斜杠 "/" 括起來
  • 各個函數的結果的 key 值為字段名.驗證函數名

如下:

type LoginInfo struct {
    UserName string `form:"username" json:"username" valid:"Required"`
    PassWord string `form:"password" json:"password" valid:"Required"`
}

3、使用方式

  • 綁定結構體變量
  • 初始化beego驗證器
  • 進行驗證
func DoValidIndex(ctx *gin.Context) {
    // 1、聲明結構體變量
    var loginInfo LoginInfo
    // 2、綁定結構體變量
    _ = ctx.ShouldBind(&loginInfo)
    // 3、初始化beego驗證器
    valid := validation.Validation{}
    // 4、開始驗證
    b, _ := valid.Valid(&loginInfo)
    if !b {
        // 5、輸出未驗證通過的錯誤信息
        // UserName.Required. can not be empty
        // PassWord.Required. can not be empty
        for _, err1 := range valid.Errors {
            fmt.Println(err1.Key)
            fmt.Println(err1.Message)
        }
    }
    fmt.Printf("UserName:%s,PassWord:%s", loginInfo.UserName, loginInfo.PassWord)
    ctx.String(http.StatusOK, "submit success!")
}

(二)驗證方法

在beego中驗證的方法有很多,比如上面的Requird方法,另外還有下面的常用方式:

  • Required 不為空,即各個類型要求不為其零值
  • Min(min int) 最小值,有效類型:int,其他類型都將不能通過驗證
  • Max(max int) 最大值,有效類型:int,其他類型都將不能通過驗證
  • Range(min, max int) 數值的范圍,有效類型:int,他類型都將不能通過驗證
  • MinSize(min int) 最小長度,有效類型:string slice,其他類型都將不能通過驗證
  • MaxSize(max int) 最大長度,有效類型:string slice,其他類型都將不能通過驗證
  • Length(length int) 指定長度,有效類型:string slice,其他類型都將不能通過驗證
  • Alpha alpha字符,有效類型:string,其他類型都將不能通過驗證
  • Numeric 數字,有效類型:string,其他類型都將不能通過驗證
  • AlphaNumeric alpha 字符或數字,有效類型:string,其他類型都將不能通過驗證
  • Match(pattern string) 正則匹配,有效類型:string,其他類型都將被轉成字符串再匹配(fmt.Sprintf(“%v”, obj).Match)
  • AlphaDash alpha 字符或數字或橫杠 -_,有效類型:string,其他類型都將不能通過驗證
  • Email 郵箱格式,有效類型:string,其他類型都將不能通過驗證
  • IP IP 格式,目前只支持 IPv4 格式驗證,有效類型:string,其他類型都將不能通過驗證
  • Base64 base64 編碼,有效類型:string,其他類型都將不能通過驗證
  • Mobile 手機號,有效類型:string,其他類型都將不能通過驗證
  • Tel 固定電話號,有效類型:string,其他類型都將不能通過驗證
  • Phone 手機號或固定電話號,有效類型:string,其他類型都將不能通過驗證
  • ZipCode 郵政編碼,有效類型:string,其他類型都將不能通過驗證

(三)自定制錯誤信息

在驗證未通過時會提示錯誤信息,但是是英文的提示,如何將其轉變成自己想要顯示的信息呢?我們只需要在第4步開始驗證之前重寫一下錯誤信息提示即可:

...
    // 3、初始化beego驗證器
    valid := validation.Validation{}
    // 定制錯誤信息
    var messages = map[string]string{
        "Required": "不能為空",
        "MinSize":  "最短長度為 %d",
        "Length":   "長度必須為 %d",
        "Numeric":  "必須是有效的數字",
        "Email":    "必須是有效的電子郵件地址",
        "Mobile":   "必須是有效的手機號碼",
    }
    validation.SetDefaultMessage(messages)

    // 4、開始驗證
    b, _ := valid.Valid(&loginInfo)
...

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM