Gin 框架 -十一-: 驗證器 Validator 使用
1. 介紹
validator 是一個開源的驗證器包,可以快速校驗輸入信息是否符合自定規則。目前Star 7.8k
, 源碼地址: https://github.com/go-playground/validator
1.1 安裝
go get github.com/go-playground/validator
1.2 引用
import "github.com/go-playground/validator"
1.3 示例
代碼:
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
// 定義一個添加用戶參數結構體
type AddUserPost struct {
Name string `json:"name" validate:"required"` //必填
Email string `json:"email" validate:"required,email"` // 必填,並且格式是email
Age uint8 `json:"age" validate:"gte=18,lte=30"` // 年齡範圍
}
// 簡單示例
func main() {
engine := gin.Default()
engine.POST("/valid", func(context *gin.Context) {
var adduserPost AddUserPost
// 接收參數
err := context.ShouldBindJSON(&adduserPost)
if err != nil {
context.JSON(500,gin.H{"msg":err})
return
}
fmt.Printf("adduserPost: %+v\n",adduserPost)
// 使用Validate驗證
validate := validator.New()
err = validate.Struct(adduserPost)
if err != nil {
fmt.Println(err)
context.JSON(500,gin.H{"msg":err.Error()})
return
}
context.JSON(200,gin.H{"msg":"success"})
})
_ = engine.Run()
}
請求:
# email不合法時
➜ curl -X POST http://127.0.0.1:8080/valid -d '{"name":"張三","email":"123","age":21}'
{"msg":"Key: 'AddUserPost.Email' Error:Field validation for 'Email' failed on the 'email' tag"}
# age 不在指定範圍時
➜ curl -X POST http://127.0.0.1:8080/valid -d '{"name":"張三","email":"123@163.com","age":17}'
{"msg":"Key: 'AddUserPost.Age' Error:Field validation for 'Age' failed on the 'gte' tag"}
# 姓名不填時
➜ curl -X POST http://127.0.0.1:8080/valid -d '{"name":"","email":"123@163.com","age":20}'
{"msg":"Key: 'AddUserPost.Name' Error:Field validation for 'Name' failed on the 'required' tag"}
2. 改成中文
2.1 代碼
package main
import (
"github.com/gin-gonic/gin"
"github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
zhs "github.com/go-playground/validator/v10/translations/zh"
)
var (
validate = validator.New() // 實例化驗證器
chinese = zh.New() // 獲取中文翻譯器
uni = ut.New(chinese, chinese) // 設置成中文翻譯器
trans, _ = uni.GetTranslator("zh") // 獲取翻譯字典
)
type User struct {
Name string `form:"name" validate:"required,min=3,max=5"`
Email string `form:"email" validate:"email"`
Age int8 `form:"age" validate:"gte=18,lte=20"`
}
func main() {
engine := gin.Default()
engine.GET("/language", func(context *gin.Context) {
var user User
err := context.ShouldBindQuery(&user)
if err != nil {
context.JSON(500, gin.H{"msg": err})
return
}
// 註冊翻譯器
_ = zhs.RegisterDefaultTranslations(validate, trans)
// 使用驗證器驗證
err = validate.Struct(user)
if err != nil {
if errors, ok := err.(validator.ValidationErrors); ok {
// 翻譯,並返回
context.JSON(500, gin.H{
"翻譯前": errors.Error(),
"翻譯後": errors.Translate(trans),
})
return
}
}
context.JSON(200,gin.H{"msg":"success"})
})
_ = engine.Run()
}
2.2 請求
# 不傳參數
➜ curl -X GET http://127.0.0.1:8080/language
{
"翻譯前":"Key: 'User.Name' Error:Field validation for 'Name' failed on the 'required' tag
Key: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag
Key: 'User.Age' Error:Field validation for 'Age' failed on the 'gte' tag",
"翻譯後":{
"User.Age":"Age必須大於或等於18",
"User.Email":"Email必須是一個有效的郵箱",
"User.Name":"Name爲必填字段"
}
}
3. 校驗規則
整理一些常用的規則
更多規則,則可查看文檔: https://github.com/go-playground/validator
4. 自定義規則
4.1 代碼
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
// 驗證pre
type CustomParam struct {
Pre string `validate:"pre=go_"`
}
func main() {
// 實例化驗證器
validate = validator.New()
// 註冊自定義標籤
_ = validate.RegisterValidation("pre", ValidatePre)
cusParam := CustomParam{
Pre: "php_",
}
err := validate.Struct(cusParam)
fmt.Println(err)
}
// 自定義驗證規則
func ValidatePre(fl validator.FieldLevel) bool {
return fl.Field().String() == "go_"
}
4.2 請求返回
Key: 'CustomParam.Pre' Error:Field validation for 'Pre' failed on the 'pre' tag
5. 在 Gin 中使用
5.1 代碼
package main
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/validator/v10"
"net/http"
"time"
)
// 定義結構體
type User struct {
Name string `form:"name" binding:"required,min=3,max=5" `
BirthDate time.Time `form:"date" binding:"required,birth" time_format:"2006-01-02"`
}
// 運行程序
func main() {
engine := gin.Default()
// 註冊自定義驗證標籤:birth
if validate,ok := binding.Validator.Engine().(*validator.Validate);ok {
validate.RegisterValidation("birth",checkBirthDate)
}
// 接收請求
engine.GET("/valid", func(context *gin.Context) {
var user User
// 集成驗證
err := context.ShouldBindQuery(&user)
if err != nil {
context.JSON(http.StatusBadRequest,gin.H{"error":err.Error()})
return
}
context.JSON(http.StatusOK,gin.H{"msg":"success"})
})
_ = engine.Run()
}
// 檢測生日
func checkBirthDate(fl validator.FieldLevel) bool {
t,ok := fl.Field().Interface().(time.Time)
if ok {
// 當前時間應該大於生日時間
if time.Now().After(t) {
return true
}
}
return false
}
5.2 請求返回
# name錯誤時
➜ curl -X GET http://127.0.0.1:8080/valid?name=張三&date=2020-01-01
{"error":"Key: 'User.Name' Error:Field validation for 'Name' failed on the 'min' tag"}
# 自定義birth格式錯誤時
➜ curl -X GET http://127.0.0.1:8080/valid?name=張是三&date=2020
{"error":"parsing time \"2020\" as \"2006-01-02\": cannot parse \"\" as \"-\""}
# 都正確
➜ curl -X GET http://127.0.0.1:8080/valid?name=張是三&date=2020-10-10
{"msg":"success"}
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/qJGza5GS8bZnnArzz1h2jg