若要將請求主體綁定到結構體中,請使用模型綁定,目前支持JSON、XML、YAML和標準表單值(foo=bar&boo=baz)的綁定。
Gin使用 [go-playground/validator.v8](https://github.com/go-playground/validator) 驗證參數,[查看完整文檔](https://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags)。
需要在綁定的字段上設置tag,比如,綁定格式為json,需要這樣設置 `json:"fieldname"` 。
此外,Gin還提供了兩套綁定方法:
- Must bind
- - Methods - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - Behavior - 這些方法底層使用 `MustBindWith`,如果存在綁定錯誤,請求將被以下指令中止 `c.AbortWithError(400, err).SetType(ErrorTypeBind)`,響應狀態代碼會被設置為400,請求頭`Content-Type`被設置為`text/plain; charset=utf-8`。注意,如果你試圖在此之后設置響應代碼,將會發出一個警告 `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`,如果你希望更好地控制行為,請使用`ShouldBind`相關的方法
- Should bind
- - Methods - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - Behavior - 這些方法底層使用 `ShouldBindWith`,如果存在綁定錯誤,則返回錯誤,開發人員可以正確處理請求和錯誤。
當我們使用綁定方法時,Gin會根據Content-Type推斷出使用哪種綁定器,如果你確定你綁定的是什么,你可以使用`MustBindWith`或者`BindingWith`。
你還可以給字段指定特定規則的修飾符,如果一個字段用`binding:"required"`修飾,并且在綁定時該字段的值為空,那么將返回一個錯誤。
```
// 綁定為json
type Login struct {
User string `form:"user" json:"user" xml:"user" binding:"required"`
Password string `form:"password" json:"password" xml:"password" binding:"required"`
}
func main() {
router := gin.Default()
// Example for binding JSON ({"user": "manu", "password": "123"})
router.POST("/loginJSON", func(c *gin.Context) {
var json Login
if err := c.ShouldBindJSON(&json); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if json.User != "manu" || json.Password != "123" {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
})
// Example for binding XML (
// <?xml version="1.0" encoding="UTF-8"?>
// <root>
// <user>user</user>
// <password>123</password>
// </root>)
router.POST("/loginXML", func(c *gin.Context) {
var xml Login
if err := c.ShouldBindXML(&xml); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if xml.User != "manu" || xml.Password != "123" {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
})
// Example for binding a HTML form (user=manu&password=123)
router.POST("/loginForm", func(c *gin.Context) {
var form Login
// This will infer what binder to use depending on the content-type header.
if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if form.User != "manu" || form.Password != "123" {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
})
// Listen and serve on 0.0.0.0:8080
router.Run(":8080")
}
```
**請求示例:**
```
$ curl -v -X POST \
http://localhost:8080/loginJSON \
-H 'content-type: application/json' \
-d '{ "user": "manu" }'
> POST /loginJSON HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.51.0
> Accept: */*
> content-type: application/json
> Content-Length: 18
>
* upload completely sent off: 18 out of 18 bytes
< HTTP/1.1 400 Bad Request
< Content-Type: application/json; charset=utf-8
< Date: Fri, 04 Aug 2017 03:51:31 GMT
< Content-Length: 100
<
{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
```
**跳過驗證:**
當使用上面的curl命令運行上面的示例時,返回錯誤,因為示例中`Password`字段使用了`binding:"required"`,如果我們使用`binding:"-"`,那么它就不會報錯。
- 簡介
- 安裝
- 快速入門
- 代碼示例
- 使用 GET, POST, PUT, PATCH, DELETE, OPTIONS
- 獲取路徑中的參數
- 獲取Get參數
- 獲取Post參數
- Get + Post 混合
- 上傳文件
- 路由分組
- 無中間件啟動
- 使用中間件
- 寫日志文件
- 自定義日志格式
- 模型綁定和驗證
- 自定義驗證器
- 只綁定Get參數
- 綁定Get參數或者Post參數
- 綁定uri
- 綁定HTML復選框
- 綁定Post參數
- XML、JSON、YAML和ProtoBuf 渲染(輸出格式)
- 設置靜態文件路徑
- 返回第三方獲取的數據
- HTML渲染
- 多個模板文件
- 重定向
- 自定義中間件
- 使用BasicAuth()(驗證)中間件
- 中間件中使用Goroutines
- 自定義HTTP配置
- 支持Let's Encrypt證書
- Gin運行多個服務
- 優雅重啟或停止
- 構建包含模板的二進制文件
- 使用自定義結構綁定表單數據
- 將請求體綁定到不同的結構體中
- HTTP/2 服務器推送
- 自定義路由日志的格式
- 設置并獲取cookie
- 測試
- 用戶