目录
  • 引言
  • 传递参数的方式
    • Header
    • URL
    • HTTP Body
  • 直接获取请求参数
    • 获取URL Path中的参数
    • 获取URL Query中的参数
    • 获取HTTP Body中的参数
  • 绑定请求参数
    • 绑定Header参数
    • 绑定URL Path参数
    • 绑定URL Query参数
    • 绑定HTTP Body参数
    • 数据校验
  • 两种方式的对比
    • 小结

      引言

      在添加路由处理函数之后,就可以在路由处理函数中编写业务处理代码了,而编写业务代码第一件事一般就是获取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获取请求参数的资料请关注其它相关文章!

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。