gin中间request body绑定到不同的结构体中
1. 一般通过调用 c.Request.Body
方法绑定数据,但不能多次调用这个方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package main import ( "fmt" "github.com/gin-gonic/gin" ) type FormA struct { Foo string `form: "foo" json: "foo" binding: "required" ` } type FormB struct { Bar string `json: "bar" binding: "required" ` } func someHandler(c *gin.Context) { // 一般通过c.request.body绑定数据,但是不能多次调用这个方法 objA := FormA{} objB := FormB{} // c.ShouldBind 使用了 c.Request.Body 不可重用 // 注意:ShouldBind方法,如果是GET请求,前台必须使用form-data传参 if err := c.ShouldBind(&objA); err == nil { fmt.Println(objA.Foo) c.String(200, "the body should be FormA" ) // 因为现在 c.Request.Body 是EOF,所以这里会报错 } else if err := c.ShouldBind(&objB); err == nil { c.String(200, "the body should be FormB" ) } else { fmt.Println(err) fmt.Println( "未执行" ) } } func main() { router := gin.Default() router.POST( "/ping" , someHandler) router.Run() } |
2. 要想多次绑定,可以使用 c.ShouldBindBodyWith
.
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
type FormA struct {
Foo string `form:"foo" json:"foo" binding:"required"`
}
type FormB struct {
Bar string `json:"bar" binding:"required"`
}
func someHandler(c *gin.Context) {
objA := FormA{}
objB := FormB{}
// 读取 c.Request.Body 并将结果存入上下文。
if err := c.ShouldBindBodyWith(&objA, binding.JSON); err == nil {
fmt.Println(objA.Foo)
c.String(200, "the body should be FormA")
// 这时, 复用存储在上下文中的 body。
} else if err := c.ShouldBindBodyWith(&objB, binding.JSON); err == nil {
c.String(200, "the body should be FormB")
} else {
fmt.Println(err)
fmt.Println("未执行")
}
}
func main() {
router := gin.Default()
router.POST("/ping", someHandler)
router.Run()
}
c.ShouldBindBodyWith
会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法。- 只有某些格式需要此功能,如
JSON
,XML
,MsgPack
,ProtoBuf
。 对于其他格式, 如Query
,Form
,FormPost
,FormMultipart
可以多次调用c.ShouldBind()
而不会造成任任何性能损失。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)