一、基本使用
在前面的文章中說明了數據綁定,就是將傳遞的參數綁定到結構體上,避免一個個的通過方法去獲取,那么又該如何對傳遞的參數值進行校驗呢?
可以在結構體上打上標簽:
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) ...