分享gin的golang web开发-模型绑定

本文介绍了Gin框架如何使用模型绑定来简化参数获取,支持JSON、XML、YAML和表单等多种参数格式。通过示例展示了绑定查询字符串、表单、JSON、路由参数、HTTP Header以及文件上传的方法。并指出在当前Gin版本中,无法通过一个方法同时绑定多个参数来源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在前两篇文章介绍路由的时候,我们了解到gin可用通过类似DefaultQuery或DefaultPostForm等方法获取到前端提交过来的参数。参数不多的情况下也很好用,但是想想看,如果接口有很多个参数的时候再用这种方法就要调用很多次获取参数的方法,本文将介绍一种新的接收参数的方法来解决这个问题:模型绑定。

gin中的模型绑定可以理解为:把请求的参数映射为一个具体的类型。gin支持JSON,XML,YAML和表单参数等多种参数格式,只需要在对应的字段上声明标签。
绑定表单或者查询字符串

type Person struct {
Name string form:"name"
Address string form:"address"
}

func startPage(c *gin.Context) {
var person Person
if c.ShouldBindQuery(&person) == nil {
log.Println(person.Name)
log.Println(person.Address)
}
c.String(200, “Success”)
}

在结构体Name字段声明form标签,并调用ShouldBindQuery方法,gin会为我们绑定查询字符串中的name和address两个参数。注意虽然我们声明了form标签,ShouldBindQuery只绑定查询字符串中的参数。

如果你想绑定表单中的参数的话结构体不用改变,需要把ShouldBindQuery方更改为ShouldBind方法。ShouldBind方法会区分GET和POST请求,如果是GET请求绑定查询字符串中的参数,如果是POST请求绑定表单参数中的内容,但是不能同时绑定两种参数。
绑定json参数

type Person struct {
Name string json:"name"
Address string json:"address"
}

func startPage(c *gin.Context) {
var person Person
if c.ShouldBind(&person) == nil {
log.Println(person.Name)
log.Println(person.Address)
}
c.String(200, “Success”)
}

json是一种常用的数据交换格式,尤其是在和web前端页面交互的时候,似乎已经成为了一种事实标准。gin绑定json格式数据方法很简单,只需要设置字段的标签为json并且调用ShouldBind方法。
其他类型参数绑定

路由参数在绑定时设置标签为uri,并调用ShouldBindUri方法。

type Person struct {
Id string uri:"id"
}

func startPage(c *gin.Context) {
var person Person
if c.ShouldBindUri(&person) == nil {
log.Println(person.Id)
}
c.String(200, “Success”)
}

绑定在HTTP Header中的参数,字段的标签设置为header,调用方法为ShouldBindHeader。

还有不太常用的数组参数是字段标签设置为form:“colors[]”,结构体例子如下:

type myForm struct {
Colors []string form:"colors[]"
}

文件上传这种场景我很少用模型绑定的方式获取参数,在gin中对于这种场景也提供了模型绑定支持。

type ProfileForm struct {
Name string form:"name"
Avatar *multipart.FileHeader form:"avatar"
// Avatars []*multipart.FileHeader form:"avatar" 多文件上传
}

func main() {
router := gin.Default()
router.POST("/profile", func(c *gin.Context) {
var form ProfileForm
if err := c.ShouldBind(&form); err != nil {
c.String(http.StatusBadRequest, “bad request”)
return
}

	err := c.SaveUploadedFile(form.Avatar, form.Avatar.Filename)
	if err != nil {
		c.String(http.StatusInternalServerError, "unknown error")
		return
	}

	c.String(http.StatusOK, "ok")
})
router.Run(":8080")

}
http://www.lexunapp.com
多种类型的模型绑定

如果我们有一个UpdateUser接口,PUT /user/:id,参数是{“nickname”: “nickname…”,“mobile”: “13322323232”}。代码如下:

type ProfileForm struct {
Id int uri:"id"
Nickname string json:"nickname" // 昵称
Mobile string json:"mobile" // 手机号
}

func main() {
router := gin.Default()
router.GET("/user/:id", func(c *gin.Context) {
var form ProfileForm
if err := c.ShouldBindUri(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{“error”: err.Error()})
return
}

	if err := c.ShouldBindJSON(&form); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.String(http.StatusOK, "ok")
})
router.Run(":8080")

}
http://www.fygqw.com
代码里调用了两次bind方法才获取到全部的参数。和gin社区沟通之后发现目前还不能调用一个方法同时绑定多个参数来源,当前gin版本为1.6.x,不知道未来会不会提供这种功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值