这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的 Content-Type 识别请求数据类型并利用反射机制自动提取请求中 QueryString、form表单、JSON、XML 等参数到结构体中。
bindJson only can bind json
下面的示例代码演示了 .ShouldBind() 强大的功能,它能够基于请求自动提取 JSON、form表单 和 QueryString 类型的数据,并把值绑定到指定的结构体对象。
[!note]- 结构体中tag 标签的作用, 不太正确 User string: 不加 tag, 就必须用结构体的名字
User string
form:"user" binding:"required", 需要有 binding 有 tag 可以用该类型的别名
![]()
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
type UserInfo struct {
Username string `form:"username" json:"user"`
Password string `form:"password" json:"pwd" `
}
func main() {
r := gin.Default()
r.LoadHTMLFiles("./index.html")
r.GET("/index", func(c *gin.Context) {
c.HTML(200, "index.html", nil)
})
//不使用ShouldBind()函数, 打印前端传递的数据
r.GET("/user", func(c *gin.Context) {
c.HTML(200, "index.html", nil)
username := c.Query("username")
password := c.Query("password")
u := UserInfo{
Username: username,
Password: password,
}
fmt.Printf("%#v\n", u) //%#v: 值的Go语法表示
//测试:127.0.0.1:8080/user?username=zeefan&password=123456
//成功得到: main.UserInfo{Username:"zeefan", Password:"123456"}
})
//使用ShouldBind()函数, 打印前端传递的数据
//前端设置好了, 点击提交按钮, 会自动跳转到/form页面
r.POST("/form", func(c *gin.Context) {
var u UserInfo
err := c.ShouldBind(&u)
if err != nil {
c.JSON(400, gin.H{
"error": err.Error(),
})
} else {
fmt.Printf("%#v\n", u)
c.JSON(200, gin.H{
"status": "ok",
})
}
})
//这个只能用 postman 来发送请求, 不能用浏览器,
//因为浏览器点击提交后会自动跳转到/form页面, 会导致后面的代码无法执行
//还有就是在网址输入, 只能发送get请求, 不能发送post请求
//不用再次定义一个结构体了, 根据传入携带的值,会自动绑到上面的结构体上
//测试:
r.POST("/json", func(c *gin.Context) {
var u UserInfo
err := c.ShouldBind(&u)
if err != nil {
c.JSON(400, gin.H{
"error": err.Error(),
})
} else {
fmt.Printf("%#v\n", u)
c.JSON(200, gin.H{
"status": "ok",
})
}
})
r.Run()
}
测试 json
main.UserInfo{Username:"user", Password:"111"}
[GIN] 2023/02/10 - 12:59:01 | 200 | 3.015792ms | 127.0.0.1 | POST "/json"
测试 form
main.UserInfo{Username:"user", Password:"111"}
[GIN] 2023/02/10 - 12:58:07 | 200 | 118.458µs | 127.0.0.1 | POST "/form"
ShouldBind 会按照下面的顺序解析请求中的数据完成绑定:
- 如果是
GET请求,只使用Form绑定引擎(query)。 - 如果是
POST请求,首先检查content-type是否为JSON或XML,然后再使用Form(form-data)。