// Binding from JSON、form、xml type Login struct { User string`form:"user" json:"user" xml:"user" binding:"required"` Password string`form:"password" json:"password" xml:"password" binding:"required"` }
funcloginFormHandler(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 }
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) } funcmain() { router := gin.Default() router.POST("/loginJSON", loginJSONHandler) // Example for binding a HTML form (user=manu&password=123) router.POST("/loginForm", loginFormHandler) router.POST("/loginXML", loginXMLHandler)
router.Run() }
测试
类型
测试命令
JSON
curl -X POST 'http://localhost:8080/loginJSON' -v -d '{"user":"manu", "password":"123"}'
XML
curl -X POST "http://localhost:8080/loginXML" -v -d '<?xml version="1.0" encoding="UTF-8"?><root><user>manu</user><password>123</password></root>'
form
curl -X POST "http://localhost:8080/loginForm" -v -d 'user=manu&password=123'
绑定Url
示例代码
此类型主要用在RESTful类型的接口,具体的示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
package main // 绑定Uri import"github.com/gin-gonic/gin"
type myForm struct { Colors []string`form:"colors[]"` }
funcformHandler(c *gin.Context) { var fakeForm myForm // If `GET`, only `Form` binding engine (`query`) used. // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`) err := c.ShouldBind(&fakeForm) if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error":err, }) } c.JSON(http.StatusOK, gin.H{ "color": fakeForm.Colors, }) }
// ShouldBindBodyWith is similar with ShouldBindWith, but it stores the request
// body into the context, and reuse when it is called again.
//
// NOTE: This method reads the body before binding. So you should use
// ShouldBindWith for better performance if you need to call only once.
type formA struct { Foo string`json:"foo" binding:"required"` }
type formB struct { Bar string`json:"bar" binding:"required"` }
funcusingShoudBindHandler(c *gin.Context) { objA := formA{} objB := formB{} // This c.ShouldBind consumes c.Request.Body and it cannot be reused. if errA := c.ShouldBindWith(&objA, binding.JSON); errA != nil { c.String(http.StatusBadRequest, "bind A JSON err:%s\n", errA.Error()) } elseif errB := c.ShouldBindWith(&objB, binding.JSON); errB != nil { // Always an error is occurred by this because c.Request.Body is EOF now. c.String(http.StatusBadRequest, "bind B JSON err:%s\n", errB.Error()) } else { c.String(http.StatusOK, "Foo:%s,Bar:%s\n", objA.Foo, objB.Bar) } }
funcusingShoudBindBodyWithHandler(c *gin.Context) { objA := formA{} objB := formB{} // This reads c.Request.Body and stores the result into the context. if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA != nil { c.String(http.StatusBadRequest, "bind A JSON err:%s\n", errA.Error()) } elseif errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB != nil { // At this time, it reuses body stored in the context. c.String(http.StatusBadRequest, "bind B JSON err:%s\n", errB.Error()) } else { c.String(http.StatusOK, "Foo:%s,Bar:%s\n", objA.Foo, objB.Bar) } }