一般通过调用 `c.Request.Body` 方法绑定数据,但不能多次调用这个方法。
```go
type formA struct {
Foo string `json:"foo" xml:"foo" binding:"required"`
}
type formB struct {
Bar string `json:"bar" xml:"bar" binding:"required"`
}
func SomeHandler(c *gin.Context) {
objA := formA{}
objB := formB{}
// c.ShouldBind 使用了 c.Request.Body,不可重用。
if errA := c.ShouldBind(&objA); errA == nil {
c.String(http.StatusOK, `the body should be formA`)
// 因为现在 c.Request.Body 是 EOF,所以这里会报错。
} else if errB := c.ShouldBind(&objB); errB == nil {
c.String(http.StatusOK, `the body should be formB`)
} else {
...
}
}
```
要想多次绑定,可以使用 `c.ShouldBindBodyWith`.
```go
func SomeHandler(c *gin.Context) {
objA := formA{}
objB := formB{}
// 读取 c.Request.Body 并将结果存入上下文。
if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
c.String(http.StatusOK, `the body should be formA`)
// 这时, 复用存储在上下文中的 body。
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
c.String(http.StatusOK, `the body should be formB JSON`)
// 可以接受其他格式
} else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
c.String(http.StatusOK, `the body should be formB XML`)
} else {
...
}
}
```
* `c.ShouldBindBodyWith` 会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法。
* 只有某些格式需要此功能,如 `JSON`, `XML`, `MsgPack`,
`ProtoBuf`。 对于其他格式, 如 `Query`, `Form`, `FormPost`, `FormMultipart`
可以多次调用 `c.ShouldBind()` 而不会造成任任何性能损失 (详见 [#1341](https://github.com/gin-gonic/gin/pull/1341))。
- 介绍
- 快速入门
- 基准测试
- 特性
- Jsoniter
- 示例
- AsciiJSON
- HTML 渲染
- HTTP2 server 推送
- JSONP
- Multipart/Urlencoded 绑定
- Multipart/Urlencoded 表单
- PureJSON
- Query 和 post form
- SecureJSON
- XML/JSON/YAML/ProtoBuf 渲染
- 上传文件
- 单文件
- 多文件
- 不使用默认的中间件
- 从 reader 读取数据
- 优雅地重启或停止
- 使用 BasicAuth 中间件
- 使用 HTTP 方法
- 使用中间件
- 只绑定 url 查询字符串
- 在中间件中使用 Goroutine
- 多模板
- 如何记录日志
- 定义路由日志的格式
- 将 request body 绑定到不同的结构体中
- 支持 Let's Encrypt
- 映射查询字符串或表单参数
- 查询字符串参数
- 模型绑定和验证
- 绑定 HTML 复选框
- 绑定 Uri
- 绑定查询字符串或表单数据
- 绑定表单数据至自定义结构体
- 自定义 HTTP 配置
- 自定义中间件
- 自定义验证器
- 设置和获取 Cookie
- 路由参数
- 路由组
- 运行多个服务
- 重定向
- 静态文件服务
- 静态资源嵌入
- 测试
- 用户
- FAQ