Go语言Gin框架获取请求参数的两种方式

 更新时间:2024年01月28日 08:26:05   作者:程序员读书  
在添加路由处理函数之后,就可以在路由处理函数中编写业务处理代码了,而编写业务代码第一件事一般就是获取HTTP请求的参数吧,Gin框架在net/http包的基础上封装了获取参数的方式,本文小编给大家介绍了获取参数的两种方式,需要的朋友可以参考下

引言

在添加路由处理函数之后,就可以在路由处理函数中编写业务处理代码了,而编写业务代码第一件事一般就是获取HTTP请求的参数吧。

传递参数的方式

在一个HTTP请求中,一般可以把上传参数分为以下三个部分:

Header

HeaderHTTP请求中一个键值对集合,HTTP规范定义了很多的Headeer,比如Content-TypeAccept等,不过也可以自定义请求头部或者响应头部。

URL

URL指的是请求路径,在请求路径上可以通过两种方式携带请求参数,一种是直接写在请求路径上的,称为URL Path

 http://localhost:8080/user/add/1

HTTP Body

HTTP Body参数是指HTTP请求的请求体所携带的参数,这部分参数会因为Content-Type不同而不同,比如当Content-Typeapplication/json时,HTTO Body携带的是一串JSON字符串。

那么,在Gin框架中,要如何获取这些请求参数呢?主要有以下两种方式:

  • 直接用Gin封装的方法获取请求参数
  • 通过绑定的方式来获取请求参数

直接获取请求参数

Gin框架在net/http包的基础上封装了获取参数的方式。

获取URL Path中的参数

在路由中使用通配符时,对应的通配符就会成为URL Path参数,调用gin.ContextParam()方法可以获取Path参数:

 package main
 ​
 func main(){
   engine := gin.Default()
   engine.GET("/user/:id", func(ctx *gin.Context) {
     id := ctx.Param("id")
     fmt.Fprintf(ctx.Writer, "你的请求id:%s", id)
   })
     engine.Run()
 }

运行后发起请求:

 $ curl http://localhost:8080/user/100
 你的请求id:100

获取URL Query中的参数

gin.Context对象提供了以下几个主要方法用于获取Query参数:

 package main
 ​
 import (
   "fmt"
 ​
   "github.com/gin-gonic/gin"
 )
 ​
 func main() {
   engine := gin.New()
   engine.GET("/user/list", func(ctx *gin.Context) {
     //获取单个值
     name := ctx.Query("name")
     //带默认值
     gender := ctx.DefaultQuery("gender", "男")
     //数组
     habits := ctx.QueryArray("habits")
     //map
     works := ctx.QueryMap("works")
     fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works)
   })
 ​
   engine.Run()
 }

运行后发起请求:

 curl --location --globoff --request GET 'http://localhost:8080/user/list?name=test&gender=%E5%A5%B3&habits=%E7%9C%8B%E4%B9%A6&habits=%E7%9C%8B%E7%94%B5%E5%BD%B1&works[%E5%86%99ppt]=1&works[%E5%86%99%E4%BB%A3%E7%A0%81]=1' \
 --header 'Content-Type: application/x-www-form-urlencoded' \
 --data-urlencode 'name=test' \
 --data-urlencode 'email=test@163.com'

获取HTTP Body中的参数

对于通过HTTP Body传上来的参数,gin.Context也提供了几种主要方法用于获取:

 package main
 ​
 import (
   "fmt"
 ​
   "github.com/gin-gonic/gin"
 )
 ​
 func main() {
   engine := gin.New()
   engine.POST("/user/add", func(ctx *gin.Context) {
     //获取单个值
     name := ctx.PostForm("name")
     //带默认值
     gender := ctx.DefaultPostForm("gender", "男")
     //数组
     habits := ctx.PostFormArray("habits")
     //map
     works := ctx.PostFormMap("works")
     fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works)
   })
 ​
   engine.Run()
 }

绑定请求参数

Gin支持绑定HeaderURL PathURL Query以及HTTP Body等不同位置数据。

绑定Header参数

绑定Header参数可以使用BindHeader()或者ShouldBindHeader()方法:

 package main
 ​
 import (
   "fmt"
   "net/http"
 ​
   "github.com/gin-gonic/gin"
 )
 ​
 type testHeader struct {
   Rate   int    `header:"Rate"`
   Domain string `header:"Domain"`
 }
 ​
 func main() {
   r := gin.Default()
   r.GET("/", func(c *gin.Context) {
     h := testHeader{}
 ​
     if err := c.ShouldBindHeader(&h); err != nil {
       c.JSON(http.StatusBadRequest, err)
       return
     }
 ​
     fmt.Printf("%#v\n", h)
     c.JSON(http.StatusOK, gin.H{"Rate": h.Rate, "Domain": h.Domain})
   })
 ​
   r.Run()
 }

运行后的请求结果:

$ curl -H "rate:300" -H "domain:music" http://localhost:8080/
{"Domain":"music","Rate":300}

绑定URL Path参数

绑定URL Path参数可以使用BindUri()或者ShouldBindUri()方法:

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type User struct {
	Name  string `uri:"name"`
  Email string `uri:"email"`
}

func main() {
	engine := gin.New()
	engine.GET("/user/list/:id/:name", func(ctx *gin.Context) {
		var u User
		if err := ctx.BindUri(&u);err != nil {
			ctx.JSON(http.StatusBadRequest, err)
			return
		}
		fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
	})
	engine.Run()
}

绑定URL Query参数

绑定URL Query参数可以使用BindQuery()ShouldBindQury()Bind()或者ShouldBind()方法:

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type User struct {
	Name  string `form:"name"`
  Email string `form:"email"`
}

func main() {
	engine := gin.New()
	engine.GET("/user/list", func(ctx *gin.Context) {
		var u User
		if err := ctx.BindQuery(&u);err != nil {
			ctx.JSON(http.StatusBadRequest, err)
			return
		}
		fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
	})

	engine.Run()
}

绑定HTTP Body参数

我们知道HTTP Body的参数会根据不同Content-Type传不同格式的数据,Gin支持以下几种Content-Type类型的绑定:

  • JSON
  • XML
  • TOML
  • YAML
  • x-www-form-urlencoded
  • multipart/form-data

注意HTTP Body的数据只在POST请求时才会进行绑定。

绑定HTTP Body参数可以用Bind()ShouldBind()方法,这两个方法会根据当前请求的Content-Type类型自动判断请求的类型。

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type User struct {
	Name  string
	Email string
}

func main() {
	engine := gin.New()
	engine.POST("/user/add", func(ctx *gin.Context) {
		var u User
		if err := ctx.Bind(&u); err != nil {
			ctx.JSON(http.StatusBadRequest, err.Error())
			return
		}
		fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
	})
	engine.Run()
}

如果明确请求数据的类型,也可以直接调用对应类型绑定的方法,比如确定是JSON格式数据的话,可以调用BindJSON()或者ShouldBindJSON()

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type User struct {
	Name  string
	Email string
}

func main() {
	engine := gin.New()
	engine.POST("/user/add", func(ctx *gin.Context) {
		var u User
		if err := ctx.BindJSON(&u); err != nil {
			ctx.JSON(http.StatusBadRequest, err.Error())
			return
		}
		fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
	})
	engine.Run()
}

对于x-www-form-urlencodedmultipart/form-data,与Qurey参数一样,结构体需要添加formtag

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type User struct {
	Name  string `form:"name"`
	Email string `form:"email"`
}

func main() {
	engine := gin.New()
	engine.POST("/user/add", func(ctx *gin.Context) {
		var u User
		if err := ctx.Bind(&u); err != nil {
			ctx.JSON(http.StatusBadRequest, err.Error())
			return
		}
		fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
	})
	engine.Run()
}

数据校验

在数据绑定的时候,也可以进行数据校验:

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type User struct {
	Name  string `binding:"required"`
	Email string `binding:"required,email"`
}

func main() {
	engine := gin.New()
	engine.POST("/user/add", func(ctx *gin.Context) {
		var u User
		if err := ctx.Bind(&u); err != nil {
			ctx.JSON(http.StatusBadRequest, err.Error())
			return
		}
		fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
	})
	engine.Run()
}

运行后发起请求的结果:

$ curl --location 'http://localhost:8080/user/add' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id":10,
    "name":"test",
    "email":"test@163.com"
}'

你输入的用户名为:test,邮箱为:test@163.com

两种方式的对比

相较于直接获取请求参数,请求数据绑定是一种更强大且优雅的参数获取方式,使用这种方式获取参数有以下几个好处:

  • 直接将所有参数绑定到一个结构体中,不需要手动一个个地获取参数。
  • 绑定后的参数会自动转换为结构体对应字段的类型,不需要手动对每个参数进行数据类型转换。
  • 在进行数据绑定的同时还可以进行数据校验。

小结

直接获取请求参数虽然没有绑定参数那么强大,但对于简单的请求来说,也是够用的,因此,我们可以根据自己的需求,选择对应的方式来获取请求参数。

以上就是Go语言Gin框架获取请求参数的两种方式的详细内容,更多关于Go Gin获取请求参数的资料请关注脚本之家其它相关文章!

相关文章

  • 一文搞懂Golang文件操作增删改查功能(基础篇)

    一文搞懂Golang文件操作增删改查功能(基础篇)

    这篇文章主要介绍了一文搞懂Golang文件操作增删改查功能(基础篇),Golang 可以认为是服务器开发语言发展的趋势之一,特别是在流媒体服务器开发中,已经占有一席之地,今天我们不聊特别深奥的机制和内容,就来聊一聊 Golang 对于文件的基本操作
    2021-04-04
  • Go调用C++动态库实现车牌识别的示例代码

    Go调用C++动态库实现车牌识别的示例代码

    本文主要介绍了如何利用C++中Opencv、TensorRT等库编译出动态库供Go调用,再写个简单的api对上传的车辆图片进行车牌识别,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • 使用Golang的channel交叉打印两个数组的操作

    使用Golang的channel交叉打印两个数组的操作

    这篇文章主要介绍了使用Golang的channel交叉打印两个数组的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Golang编写自定义IP限流中间件的方法详解

    Golang编写自定义IP限流中间件的方法详解

    这篇文章给大家详细的介绍了Golang编写自定义IP限流中间件的方法,文章通过代码实例介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-09-09
  • 学习GO编程必备知识汇总

    学习GO编程必备知识汇总

    这篇文章主要介绍了学习GO编程必备知识汇总的相关资料,需要的朋友可以参考下
    2016-07-07
  • Go语言接口用法实例

    Go语言接口用法实例

    这篇文章主要介绍了Go语言接口用法,实例分析了Go语言接口的功能、定义及使用技巧,需要的朋友可以参考下
    2015-02-02
  • golang中的io.ReadCloser与ioutil.NopCloser使用

    golang中的io.ReadCloser与ioutil.NopCloser使用

    这篇文章主要介绍了golang中的io.ReadCloser与ioutil.NopCloser使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Go语言实现对XML的读取和修改

    Go语言实现对XML的读取和修改

    这篇文章主要为大家详细介绍了Go语言实现对XML的读取和修改的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-12-12
  • Go递归修改文件名的实例代码

    Go递归修改文件名的实例代码

    这篇文章主要介绍了Go递归修改文件名的实例代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的饿参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Air实现Go程序实时热重载使用过程解析示例

    Air实现Go程序实时热重载使用过程解析示例

    这篇文章主要为大家介绍了Air实现Go程序实时热重载使用过程解析示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04

最新评论