gin框架中的引數驗證
阿新 • • 發佈:2021-12-13
結構體驗證
用gin框架的資料驗證,可以不用解析資料,減少if else,會簡潔許多。
- 處理請求方法
func structValidator(context *gin.Context) {
var person Person
if err := context.ShouldBind(&person); err != nil {
fmt.Println(err)
context.String(http.StatusBadRequest, "failed")
return
}
context.JSON(http.StatusOK, &person)
}
- 驗證結構體
type Person struct {
// 不能為空並且大於10
Age int `json:"age" form:"age" binding:"required,gt=10"`
Name string `json:"name" form:"name" binding:"required"`
Birthday time.Time `json:"birthday" form:"birthday" time_format:"2006-01-02 15:04:05" time_utc:"0"`
}
自定義驗證 V10版本
依賴:github.com/go-playground/validator/v10
type Person struct { // 不能為空並且大於10 Age int `json:"age" form:"age" binding:"required,gt=10"` // 2、在引數 binding 上使用自定義的校驗方法函式註冊時候的名稱 Name string `json:"name" form:"name" binding:"NotNullAndAdmin"` Birthday time.Time `json:"birthday" form:"birthday" time_format:"2006-01-02"` } func NotNullAndAdmin(fl validator.FieldLevel) bool { if value, ok := fl.Field().Interface().(string); ok { // 欄位不能為空,並且不等於 admin return value != "" && !("admin" == value) } return false } func RegisterValidator() { // 將我們自定義的校驗方法註冊到validator中 if v, ok := binding.Validator.Engine().(*validator.Validate); ok { // 這裡的 key 和 fn 可以不一樣最終在 struct 使用的是 key v.RegisterValidation("NotNullAndAdmin", NotNullAndAdmin) } } func main() { // 註冊驗證器 blog.RegisterValidator() }
自定義驗證器 V8版本
點選檢視程式碼
package main import ( "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "gopkg.in/go-playground/validator.v8" "net/http" "reflect" "time" ) //binding 繫結一些驗證請求引數,自定義標籤bookabledate表示可預約的時期 type Booking struct { CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"` CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckOut,bookabledate" time_format:"2006-01-02"` } //定義bookabledate標籤對應的驗證方法 func bookableDate( v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string, ) bool { if date, ok := field.Interface().(time.Time); ok { today := time.Now() if date.Unix() > today.Unix() { return true } } return false } func main() { route := gin.Default() //將驗證方法註冊到驗證器中 if v, ok := binding.Validator.Engine().(*validator.Validate); ok { v.RegisterValidation("bookabledate", bookableDate) } route.GET("/bookable", getBookable) route.Run(":8080") } func getBookable(c *gin.Context) { var b Booking if err := c.ShouldBindWith(&b, binding.Query); err == nil { c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"}) } else { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) } }
V10 版本示例2
func RegisterValidator() {
// 將我們自定義的校驗方法註冊到validator中
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
// 這裡的 key 和 fn 可以不一樣最終在 struct 使用的是 key
v.RegisterValidation("NotNullAndAdmin", NotNullAndAdmin)
v.RegisterValidation("bookableDate", bookableDate)
}
}
type Booking struct {
// 定義一個預約的時間大於今天的時間
CheckIn time.Time `json:"check_in" binding:"required,bookableDate" time_format:"2006-01-02"`
// gtfield=CheckIn退出的時間大於預約的時間
CheckOut time.Time `json:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`
}
func bookableDate(fl validator.FieldLevel) bool {
if v, ok := fl.Field().Interface().(time.Time); ok {
currentTime := time.Now().Unix()
if currentTime > v.Unix() {
return false
}
}
return true
}
請求引數:
{
"check_in": "2021-12-13T8:16:25Z", // UTC時區
"check_out": "2021-12-13T16:16:26+08:00" // 中國:東八時區
}