当前位置:   article > 正文

探索Gin框架:Golang Gin框架请求参数的获取

探索Gin框架:Golang Gin框架请求参数的获取

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie

前言

我们在专栏的前面几篇文章内讲解了Gin框架的路由配置,服务启动等内容。

专栏地址:https://blog.csdn.net/qq_35716689/category_12575301.html

在我们平常添加路由处理函数之后,就可以在路由处理函数中编写业务处理代码了,但在此之前我们往往需要获取请求参数,本文就详细的讲解下gin获取请求参数常见的几种方式。

目录

前言

传递参数的方式

Header

URL

HTTP Body

直接获取请求参数

获取URL Path中的参数

获取URL Query中的参数

获取HTTP Body中的参数

绑定请求参数

绑定Header参数

绑定URL Path参数

绑定URL Query参数

绑定HTTP Body参数

数据校验

两种方式的对比

小结


传递参数的方式

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

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

URL

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

http://localhost:8080/user/add

在URL上传递参数的另外一种方式就是URL Query,URL Query参数是指跟在?后面的键值对集合,多个参数之间以&分隔的:

http://localhost:8080/user/add?name=小明&gender=男

HTTP Body

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

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

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

直接获取请求参数

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

获取URL Path中的参数

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

  1.  package main
  2.  ​
  3.  func main(){
  4.   engine := gin.Default()
  5.   engine.GET("/user/:id", func(ctx *gin.Context) {
  6.   id := ctx.Param("id")
  7.   fmt.Fprintf(ctx.Writer, "你的请求id:%s", id)
  8.   })
  9.   engine.Run()
  10.  }

运行后发起请求:

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

获取URL Query中的参数

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

  1.  package main
  2.  ​
  3.  import (
  4.   "fmt"
  5.  ​
  6.   "github.com/gin-gonic/gin"
  7.  )
  8.  ​
  9.  func main() {
  10.   engine := gin.New()
  11.   engine.GET("/user/list", func(ctx *gin.Context) {
  12.   //获取单个值
  13.   name := ctx.Query("name")
  14.   //带默认值
  15.   gender := ctx.DefaultQuery("gender", "男")
  16.   //数组
  17.   habits := ctx.QueryArray("habits")
  18.   //map
  19.   works := ctx.QueryMap("works")
  20.   fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works)
  21.   })
  22.  ​
  23.   engine.Run()
  24.  }

运行后发起请求:

  1. curl -X GET "http://localhost:8080/user/list?name=John&gender=男&habits[]=reading&habits[]=sports&works[teacher]=math&works[engineer]=computer"
  2. John,男,[reading sports],map[engineer:computer teacher:math]

获取HTTP Body中的参数

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

  1.  package main
  2.  ​
  3.  import (
  4.   "fmt"
  5.  ​
  6.   "github.com/gin-gonic/gin"
  7.  )
  8.  ​
  9.  func main() {
  10.   engine := gin.New()
  11.   engine.POST("/user/add", func(ctx *gin.Context) {
  12.   //获取单个值
  13.   name := ctx.PostForm("name")
  14.   //带默认值
  15.   gender := ctx.DefaultPostForm("gender", "男")
  16.   //数组
  17.   habits := ctx.PostFormArray("habits")
  18.   //map
  19.   works := ctx.PostFormMap("works")
  20.   fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works)
  21.   })
  22.  ​
  23.   engine.Run()
  24.  }

绑定请求参数

Gin支持绑定Header,URL Path,URL Query以及HTTP Body等不同位置数据。

绑定Header参数

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

  1.  package main
  2.  ​
  3.  import (
  4.    "fmt"
  5.    "net/http"
  6.  ​
  7.    "github.com/gin-gonic/gin"
  8.  )
  9.  ​
  10.  type testHeader struct {
  11.    Rate   int    `header:"Rate"`
  12.    Domain string `header:"Domain"`
  13.  }
  14.  ​
  15.  func main() {
  16.    r := gin.Default()
  17.    r.GET("/", func(c *gin.Context) {
  18.      h := testHeader{}
  19.  ​
  20.      if err := c.ShouldBindHeader(&h); err != nil {
  21.        c.JSON(http.StatusBadRequest, err)
  22.        return
  23.     }
  24.  ​
  25.      fmt.Printf("%#v\n", h)
  26.      c.JSON(http.StatusOK, gin.H{"Rate": h.Rate, "Domain": h.Domain})
  27.   })
  28.  ​
  29.    r.Run()
  30.  }

运行后的请求结果:

  1. $ curl -H "rate:300" -H "test:123" http://localhost:8080/
  2. {"Test":"123","Rate":300}

绑定URL Path参数

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

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/gin-gonic/gin"
  6. )
  7. type User struct {
  8. Name string `uri:"name"`
  9. Email string `uri:"email"`
  10. }
  11. func main() {
  12. engine := gin.New()
  13. engine.GET("/user/list/:email/:name", func(ctx *gin.Context) {
  14. var u User
  15. if err := ctx.BindUri(&u);err != nil {
  16. ctx.JSON(http.StatusBadRequest, err)
  17. return
  18. }
  19. fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
  20. })
  21. engine.Run()
  22. }

运行后的请求结果: 

  1. curl -X GET "http://localhost:8080/user/list/john@163.com/john
  2. 你输入的用户名为:john,邮箱为:john@163.com

绑定URL Query参数

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

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/gin-gonic/gin"
  6. )
  7. type User struct {
  8. Name string `form:"name"`
  9. Email string `form:"email"`
  10. }
  11. func main() {
  12. engine := gin.New()
  13. engine.GET("/user/list", func(ctx *gin.Context) {
  14. var u User
  15. if err := ctx.BindQuery(&u);err != nil {
  16. ctx.JSON(http.StatusBadRequest, err)
  17. return
  18. }
  19. fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
  20. })
  21. engine.Run()
  22. }

运行后的请求结果:

  1. curl -X GET "http://localhost:8080/user/list?email=john@163.com&name=john
  2. 你输入的用户名为:john,邮箱为:john@163.com

绑定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类型自动判断请求的类型。

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/gin-gonic/gin"
  6. )
  7. type User struct {
  8. Name string
  9. Email string
  10. }
  11. func main() {
  12. engine := gin.New()
  13. engine.POST("/user/add", func(ctx *gin.Context) {
  14. var u User
  15. if err := ctx.Bind(&u); err != nil {
  16. ctx.JSON(http.StatusBadRequest, err.Error())
  17. return
  18. }
  19. fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
  20. })
  21. engine.Run()
  22. }

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

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/gin-gonic/gin"
  6. )
  7. type User struct {
  8. Name string
  9. Email string
  10. }
  11. func main() {
  12. engine := gin.New()
  13. engine.POST("/user/add", func(ctx *gin.Context) {
  14. var u User
  15. if err := ctx.BindJSON(&u); err != nil {
  16. ctx.JSON(http.StatusBadRequest, err.Error())
  17. return
  18. }
  19. fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
  20. })
  21. engine.Run()
  22. }

对于x-www-form-urlencoded和multipart/form-data,与Qurey参数一样,结构体需要添加form的tag:

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/gin-gonic/gin"
  6. )
  7. type User struct {
  8. Name string `form:"name"`
  9. Email string `form:"email"`
  10. }
  11. func main() {
  12. engine := gin.New()
  13. engine.POST("/user/add", func(ctx *gin.Context) {
  14. var u User
  15. if err := ctx.Bind(&u); err != nil {
  16. ctx.JSON(http.StatusBadRequest, err.Error())
  17. return
  18. }
  19. fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
  20. })
  21. engine.Run()
  22. }

数据校验

在数据绑定的时候,也可以进行数据校验,这里我们为User结构体的标签添加了required属性,要求这个字段必须要有:

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/gin-gonic/gin"
  6. )
  7. type User struct {
  8. Name string `binding:"required"`
  9. Email string `binding:"required"`
  10. }
  11. func main() {
  12. engine := gin.New()
  13. engine.POST("/user/add", func(ctx *gin.Context) {
  14. var u User
  15. if err := ctx.Bind(&u); err != nil {
  16. ctx.JSON(http.StatusBadRequest, err.Error())
  17. return
  18. }
  19. fmt.Fprintf(ctx.Writer, "你输入的用户名为:%s,邮箱为:%s\n", u.Name, u.Email)
  20. })
  21. engine.Run()
  22. }

两种方式的对比

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

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

小结

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/89244
推荐阅读
相关标签
  

闽ICP备14008679号