2

在前几篇文章中,数据或者参数的绑定需要一个一个的绑定,比如这样:

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?Username=bill&Password=111111123>

这个链接的两个参数取到,可以这样写:

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

LiberHome
409 声望1.1k 粉丝

有问题 欢迎发邮件 📩 liberhome@163.com