在前几篇文章中,数据或者参数的绑定须要一个一个的绑定,比方这样:
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
// 建设一个构造体来存储数据
type UserInfo struct {
username string
password string
}
func main() {r := gin.Default()
r.GET("/user", func(c *gin.Context) {username := c.Query("username")
passsword := c.Query("password")
u := UserInfo{
username: username,
password: passsword,
}
fmt.Printf("%v\n", u)
// 给这个申请返回一个 JSON 数据
c.JSON(http.StatusOK, gin.H{"message": "ok",})
})
r.Run(":9090")
}
后果如下:
然而一单参数略微多一点,这样一个一个的绑定就太麻烦了,这里介绍一下 Gin 框架中的 ShouldBind(), 它用于将申请携带的参数和后端的构造体绑定起来,比方下面咱们 UserInfo 这个构造体有 username 和 password 两个字段,如果申请中呈现这两个字段 ShouldBind() 就会主动帮咱们取出这两个值,而后伴咱们做一个构造体的初始化,咱们就能够失去一个 UserInfo 类型的变量。
ShouldBind() 的应用过程须要留神:
- ShouldBind 接管的是构造体对象的地址(& 对象名字),而不是对象
- 构造体的每一个字段首字母要大写(相似 Java public 申明)
- 构造体该打标签要打,发送 json 格局的申请要打 json 标签,地址栏中发送申请要打 form 标签。
ShouldBind 模仿 queryString
举个例子:如果要想把 http://127.0.0.1:9090/user?Us… 这个链接的两个参数取到,能够这样写:
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
// 建设一个构造体来存储数据
type UserInfo struct {
Username string
Password string
}
func main() {r := gin.Default()
r.GET("/user", func(c *gin.Context) {//username := c.Query("username")
//passsword := c.Query("password")
//u := UserInfo{
// username: username,
// password: passsword,
//}
// 申明一个 UserInfo 类型的变量 u
var u UserInfo
// 这里把地址传过来
err := c.ShouldBind(&u)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),
})
} else {fmt.Printf("%#v\n", u)
c.JSON(http.StatusOK, gin.H{"status": "ok",})
}
})
r.Run(":9090")
}
后果如下:
ShouldBind 模仿 PostForm
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
// 建设一个构造体来存储数据
type UserInfo struct {
Username string
Password string
}
func main() {r := gin.Default()
r.GET("/user", func(c *gin.Context) {//username := c.Query("username")
//passsword := c.Query("password")
//u := UserInfo{
// username: username,
// password: passsword,
//}
// 申明一个 UserInfo 类型的变量 u
var u UserInfo
// 这里把地址传过来
err := c.ShouldBind(&u)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),
})
} else {fmt.Printf("%#v\n", u)
c.JSON(http.StatusOK, gin.H{"status": "ok",})
}
})
r.POST("/form", func(c *gin.Context) {
var u UserInfo
// 这里把地址传过来
err := c.ShouldBind(&u)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),
})
} else {fmt.Printf("%#v\n", u)
c.JSON(http.StatusOK, gin.H{"status": "ok",})
}
})
r.Run(":9090")
}
用 APIPOST 或者 POSTMAN 在 POST 申请中的 body 外面 mock 一下数据:
terminal 外面的后果如下:
ShouldBind 模仿绑定 JSON 数据(当前常常用,因为当前大部分都是前后端拆散的,须要这样绑定 JSON 数据)
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
// 建设一个构造体来存储数据
type UserInfo struct {
Username string
Password string
}
func main() {r := gin.Default()
r.GET("/user", func(c *gin.Context) {//username := c.Query("username")
//passsword := c.Query("password")
//u := UserInfo{
// username: username,
// password: passsword,
//}
// 申明一个 UserInfo 类型的变量 u
var u UserInfo
// 这里把地址传过来
err := c.ShouldBind(&u)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),
})
} else {fmt.Printf("%#v\n", u)
c.JSON(http.StatusOK, gin.H{"status": "ok",})
}
})
r.POST("/form", func(c *gin.Context) {
var u UserInfo
// 这里把地址传过来
err := c.ShouldBind(&u)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),
})
} else {fmt.Printf("%#v\n", u)
c.JSON(http.StatusOK, gin.H{"status": "ok",})
}
})
r.POST("/json", func(c *gin.Context) {
var u UserInfo
// 这里把地址传过来
err := c.ShouldBind(&u)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),
})
} else {fmt.Printf("%#v\n", u)
c.JSON(http.StatusOK, gin.H{"status": "ok",})
}
})
r.Run(":9090")
}
用 APIPOST 来 mock 的数据如下:
terminal 后果如下:
其实察看以上三局部的代码,无论是 QueryString、PostForm 还是 JSON 数据的绑定,这部分的代码都是截然不同的:
var u UserInfo
// 这里把地址传过来
err := c.ShouldBind(&u)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),
})
} else {fmt.Printf("%#v\n", u)
c.JSON(http.StatusOK, gin.H{"status": "ok",})
}
阐明 shouBind() 办法能够依据申请中 contentType 的不同类型,采纳不同的形式进行解决。
参考:bilibili