Gin是一個使用Golang開發的輕量級Web框架,它提供了快速構建高性能Web應用程序的工具和庫。然而,在使用Gin開發Web應用時,我們可能會遇到一些問題,比如json數組驗證無法正常工作,下面我們來詳細解釋這個問題。
var jsonExample = ` { "name": "John", "age": 20, "hobbies": ["reading", "swimming"], "friends": [ { "name": "Jerry", "age": 22 }, { "name": "Lisa", "age": 21 } ] }` type Person struct { Name string `json:"name" binding:"required"` Age int `json:"age" binding:"required"` // hobbies 驗證器無法正常工作 Hobbies []string `json:"hobbies" binding:"required,dive,endswith=g"` Friends []Friend `json:"friends" binding:"required,dive"` } type Friend struct { Name string `json:"name" binding:"required"` Age int `json:"age" binding:"required"` } func main() { r := gin.Default() r.POST("/", func(c *gin.Context) { var p Person err := c.BindJSON(&p) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, p) }) r.Run(":8080") }
從上面的代碼中可以看到,在Person結構體中,我們為Hobbies屬性定義了json數組驗證器,并期望它是required的、dive的、endswith=g的。然而,當我們向API發送一個json請求時,我們會收到以下錯誤響應:
{ "error": "Key: 'Person.Hobbies[0]' Error:Field validation for 'Endswith' failed on the 'g' tag\nKey: 'Person.Hobbies[1]' Error:Field validation for 'Endswith' failed on the 'g' tag\n" }
從錯誤響應中可以看出,驗證器似乎不能正確驗證json數組。其實,問題不在數組驗證本身。問題出在dive驗證器。
dive驗證器用于執行嵌套驗證,它的作用是解包數組或切片,并將fn應用于數組或切片的每個元素。然而,它只能與struct、map和slice類型一起使用,并且不能與數組類型一起使用。
所以,如果我們想要在json數組中驗證每個元素,我們應該使用slice而不是數組,因為slice與數組的區別在于slice沒有固定大小。
type Person struct { Name string `json:"name" binding:"required"` Age int `json:"age" binding:"required"` Hobbies []string `json:"hobbies" binding:"required,dive,endswith=g"` Friends []Friend `json:"friends" binding:"required,dive"` } type Person struct { Name string `json:"name" binding:"required"` Age int `json:"age" binding:"required"` Hobbies []string `json:"hobbies" binding:"required,dive,endswith=g"` Friends []Friend `json:"friends" binding:"required,dive"` } func main() { r := gin.Default() r.POST("/", func(c *gin.Context) { var p Person err := c.BindJSON(&p) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, p) }) r.Run(":8080") }
通過使用slice類型,我們現在可以正確地驗證json數組中的每個元素了。