Gin 模型绑定与验证
539 字
3 分钟
Gin 模型绑定与验证
使用时,需要在要绑定的所有字段上,设置相应的tag。 例如,使用 JSON 绑定时,设置字段标签为 json:"fieldname"。
Gin提供了两类绑定方法:
- Type - 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会输出日志[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422。 如果您希望更好地控制绑定,考虑使用ShouldBind等效方法。
- Methods -
- Type - Should bind
- Methods -
ShouldBind,ShouldBindJSON,ShouldBindXML,ShouldBindQuery,ShouldBindYAML - Behavior - 这些方法属于
ShouldBindWith的具体调用。 如果发生绑定错误,Gin 会返回错误并由开发者处理错误和请求。
- Methods -
使用 Bind 方法时,Gin 会尝试根据 Content-Type 推断如何绑定。 如果你明确知道要绑定什么,可以使用 MustBindWith 或 ShouldBindWith。
你也可以指定必须绑定的字段。 如果一个字段的 tag 加上了 binding:"required",但绑定时是空值, Gin 会报错。
如果结构体的某个字段本身也是一个结构体(嵌套结构体),为了正确验证,该结构体的字段也需要添加 binding:"required" 标签。
// 绑定 JSONtype 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()
// 绑定 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"}) })
// 绑定 XML ( // <?xml version="1.0" encoding="UTF-8"?> // <root> // <user>manu</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"}) })
// 绑定 HTML 表单 (user=manu&password=123) router.POST("/loginForm", func(c *gin.Context) { var form Login // 根据 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"}) })
// 监听并在 0.0.0.0:8080 上启动服务 router.Run(":8080")}文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
Go 的 Small Interface 设计理念
编程语言从编译模型看 Go 与 C++ 契约方式的差异:消费者定义小接口与隐式实现的哲学。
2
Go 的 map
编程语言Go map 的引用类型本质、key 的约束、nil 行为与初始化示例。
3
Python StrEnum 与 Literal 的区别
编程语言StrEnum(运行时枚举)与 Literal(纯类型约束)的差异、对比表与 FastAPI/Pydantic 选型建议。
4
Grafana 可视化与监控
云原生与运维Grafana 的定位、常见数据源与 Grafana + Prometheus 经典监控链路。
5
微服务之间如何传递 trace
后端开发跨服务传递的是 trace 上下文而非 tracer:HTTP header、gRPC metadata 与 MQ 消息头的标准做法。
随机文章随机推荐











