从零开发区块链应用(七)--gin框架参数获取

gin框架参数获取

一、获取query参数

query指的是URL ? 后面携带的参数,例如user/info?username=张三&password=123。获取请求的query参数的方法如下:

  • 当使用DefaultQuery时,如果没有获取到浏览器输入的username,则返回设置defaultValue
username := ctx.DefaultQuery("username", "杰哥的技术杂货铺")
  • 当使用Query时,如果没有获取到浏览器输入的password,则默认返回""空串
password := ctx.Query("password")

完整示例如下

浏览器输入为:

http://127.0.0.1:8000/user/info?username=张三&password=123456

服务端返回为:

{"message":"success","password":"123456","username":"张三"}

后端处理逻辑如下:

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {

    //设置gin模式
    gin.SetMode(gin.ReleaseMode)
    //创建一个新的路由引擎
    r := gin.New()
    // GET:请求方式; /user/info:请求的路径
    r.GET("/user/info", func(ctx *gin.Context) {
        // 当使用DefaultQuery时,如果没有获取到浏览器输入的username,则返回设置defaultValue给username
        username := ctx.DefaultQuery("username", "杰哥的技术杂货铺")
        // 当使用Query时,如果没有获取到浏览器输入的password,则默认返回""空串
        password := ctx.Query("password")
        // 返回json给浏览器
        ctx.JSON(http.StatusOK, gin.H{
            "message":  "success",
            "username": username,
            "password": password,
        })
    })
    // 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
    r.Run(":8000")
}

注:一般使用Query方法

二、获取form表单参数

当前端请求的数据通过form表单提交时,例如向/user/info发送一个POST请求,获取请求数据的方式如下:

完整示例如下

后端处理逻辑如下:

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    //设置gin模式
    gin.SetMode(gin.ReleaseMode)
    //创建一个新的路由引擎
    r := gin.New()
    // POST:请求方式; /user/info:请求的路径
    r.POST("/user/info", func(ctx *gin.Context) {
        //提交单个表单数据时
        //如果没有在请求中获取到表单参数,则返回默认值"张三"
        username := ctx.DefaultPostForm("username", "张三")
        //如果没有在请求中获取到表单参宿,则返回""空串
        password := ctx.PostForm("password")
        //提交复选框多个数据时
        info := ctx.PostFormArray("info")
        // 输出json结果给调用方
        ctx.JSON(http.StatusOK, gin.H{
            "message":  "success",
            "username": username,
            "password": password,
            "info":     info,
        })
    })
    // 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
    r.Run(":8000")
}

注:一般使用PostForm方法

三、获取JSON参数

当前端请求的数据通过json提交时,例如向/user/info发送一个POST请求,则获取请求参数的方式如下:

  • 使用postman配置json请求如下:

image

  • 后端处理逻辑如下:
package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

type User struct {
    // 如果想要指定返回的json为其他别名,则可以使用`json:"username"`定义json格式的别名
    UserName string `json:"username"`
    PassWord string `json:"password"`
}

func main() {
    //设置gin模式
    gin.SetMode(gin.ReleaseMode)
    //创建一个新的路由引擎
    r := gin.New()
    // POST:请求方式; /user/info:请求的路径
    r.POST("/user/info", func(ctx *gin.Context) {
        // 创建一个json结构体实例并与请求json参数绑定
        userBody := &User{}
        err := ctx.BindJSON(&userBody)
        // 判断json请求数据结构与定义的结构体有没有绑定成功
        if err != nil {
            ctx.JSON(200, gin.H{
                "err_no":  400,
                "message": "Post Data Err",
            })
        } else {
            ctx.JSON(http.StatusOK, gin.H{
                "username": userBody.UserName,
                "password": userBody.PassWord,
            })
        }
    })
    // 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
    r.Run(":8080")
}
  • 返回结果如下所示: image

四、获取path参数

请求的参数通过URL路径传递,例如/user/info/张三/123456。获取请求URL路径中的参数的方式如下。

  • 浏览器输入为:
127.0.0.1:8080/user/info/张三/123456
  • 后端处理逻辑如下:
package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    //设置gin模式
    gin.SetMode(gin.ReleaseMode)
    //创建一个新的路由引擎
    r := gin.New()
    // GET:请求方式; /user/info:请求的路径
    r.GET("/user/info/:username/:password", func(ctx *gin.Context) {
        // 如果没有获取到相关路径参数,则返回""空串
        username := ctx.Param("username")
        password := ctx.Param("password")

        //返回结果给调用方
        ctx.JSON(http.StatusOK, gin.H{
            "message":  "success",
            "username": username,
            "password": password,
        })
    })
    // 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
    r.Run(":8080")
}
  • 返回结果如下:
{"message":"success","password":"123456","username":"张三"}

注意如下请求路由定义方式是不合法的,如果想要定义两个类似的请求路由,可以加入版本号进行区分,如/user/v1/info/——>/user/v2/info/,版本号从v1到v2。

错误写法:

// GET:请求方式; /hello:请求的路径
r.GET("/user/info/:username/:password", func(c *gin.Context) {

})
r.GET("/user/info/:username/:password", func(c *gin.Context) {

})

正确写法:

r.GET("/user/v1/info/:username/:password", func(ctx *gin.Context) {
        // 如果没有获取到相关路径参数,则返回""空串
        username := ctx.Param("username")
        password := ctx.Param("password")

        //返回结果给调用方
        ctx.JSON(http.StatusOK, gin.H{
            "message":  "success",
            "username": username,
            "password": password,
        })
    })

    r.GET("/user/v2/info/:username/:address", func(ctx *gin.Context) {
        // 如果没有获取到相关路径参数,则返回""空串
        username := ctx.Param("username")
        address := ctx.Param("address")

        //返回结果给调用方
        ctx.JSON(http.StatusOK, gin.H{
            "message":  "success",
            "username": username,
            "address":  address,
        })
    })

五、参数绑定

为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中QueryString、form表单、JSON、XML等参数到结构体中。 下面的示例代码演示了.ShouldBind()强大的功能,它能够基于请求自动提取JSON、form表单和QueryString类型的数据,并把值绑定到指定的结构体对象。

  • 通过query方式请求,此时输入url,不需要其他配置: image
  • 通过json方式请求,输入url,输入json body,输入Content-Type=application/json。 image
  • 后端处理逻辑如下:
package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

// Login Binding from JSON
type Login struct {
    UserName string `form:"username" json:"username" binding:"required"`
    Password string `form:"password" json:"password" binding:"required"`
}

func main() {
    //设置gin模式
    gin.SetMode(gin.ReleaseMode)
    //创建一个新的路由引擎
    r := gin.New()
    // 绑定JSON的示例 ({"username": "张三", "password": "123456"})
    r.POST("/loginJSON", func(ctx *gin.Context) {
        // 创建一个结构体类型实例
        login := Login{}
        if err := ctx.ShouldBind(&login); err == nil {
            ctx.JSON(http.StatusOK, gin.H{
                "message":  "login with json query",
                "username": login.UserName,
                "password": login.Password,
            })
        } else {
            ctx.JSON(http.StatusBadRequest, gin.H{
                "err_no": err.Error(),
            })
        }
    })

    // 绑定form表单示例 (user=张三&password=123456)
    r.POST("/loginForm", func(ctx *gin.Context) {
        login := Login{}
        // ShouldBind()会根据请求的Content-Type自行选择绑定器
        if err := ctx.ShouldBind(&login); err == nil {
            ctx.JSON(http.StatusOK, gin.H{
                "message":  "login with form query",
                "username": login.UserName,
                "password": login.Password,
            })
        } else {
            ctx.JSON(http.StatusBadRequest, gin.H{
                "error": err.Error(),
            })
        }
    })

    // 绑定QueryString示例 (/loginQuery?user=张三&password=123456)
    r.GET("/loginQuery", func(ctx *gin.Context) {
        login := Login{}
        // ShouldBind()会根据请求的Content-Type自行选择绑定器
        if err := ctx.ShouldBind(&login); err == nil {
            ctx.JSON(http.StatusOK, gin.H{
                "message":  "login with querystring query",
                "username": login.UserName,
                "password": login.Password,
            })
        } else {
            ctx.JSON(http.StatusBadRequest, gin.H{
                "error": err.Error(),
            })
        }
    })

    // 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
    r.Run(":8080")
}

ShouldBind会按照下面的顺序解析请求中的数据完成绑定:

  • 如果是 GET 请求,只使用 Form 绑定引擎(query)。
  • 如果是 POST 请求,首先检查 content-type 是否为 JSON 或 XML,然后再使用 Form(form-data)。

至此,我们学会了gin框架如何获取请求参数的方式。


本系列文章: 从零开发区块链应用(一)--golang配置文件管理工具viper 从零开发区块链应用(二)--mysql安装及数据库表的安装创建 从零开发区块链应用(三)--mysql初始化及gorm框架使用 从零开发区块链应用(四)--自定义业务错误信息 从零开发区块链应用(五)--golang网络请求 从零开发区块链应用(六)--gin框架使用 从零开发区块链应用(七)--gin框架参数获取 从零开发区块链应用(八)--结构体初识 从零开发区块链应用(九)--区块链结构体创建 从零开发区块链应用(十)--golang协程使用 从零开发区块链应用(十一)--以太坊地址生成 从零开发区块链应用(十二)--以太坊余额查询 从零开发区块链应用(十三)--以太坊区块查询 从零开发区块链应用(十四)--以太坊交易哈希查询 从零开发区块链应用(十五)--以太坊交易匹配查询 从零开发区块链应用(十六)--ETH转账处理


点赞 2
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
杰哥的技术杂货铺
杰哥的技术杂货铺
0x6e60...2aa2
江湖只有他的大名,没有他的介绍。