Go語言Gin框架獲取請求參數(shù)的兩種方式
引言
在添加路由處理函數(shù)之后,就可以在路由處理函數(shù)中編寫業(yè)務(wù)處理代碼了,而編寫業(yè)務(wù)代碼第一件事一般就是獲取HTTP請求的參數(shù)吧。
傳遞參數(shù)的方式
在一個HTTP請求中,一般可以把上傳參數(shù)分為以下三個部分:
Header
Header是HTTP請求中一個鍵值對集合,HTTP規(guī)范定義了很多的Headeer,比如Content-Type,Accept等,不過也可以自定義請求頭部或者響應(yīng)頭部。
URL
URL指的是請求路徑,在請求路徑上可以通過兩種方式攜帶請求參數(shù),一種是直接寫在請求路徑上的,稱為URL Path:
http://localhost:8080/user/add/1
HTTP Body
HTTP Body參數(shù)是指HTTP請求的請求體所攜帶的參數(shù),這部分參數(shù)會因為Content-Type不同而不同,比如當Content-Type為application/json時,HTTO Body攜帶的是一串JSON字符串。
那么,在Gin框架中,要如何獲取這些請求參數(shù)呢?主要有以下兩種方式:
- 直接用
Gin封裝的方法獲取請求參數(shù) - 通過綁定的方式來獲取請求參數(shù)
直接獲取請求參數(shù)
Gin框架在net/http包的基礎(chǔ)上封裝了獲取參數(shù)的方式。
獲取URL Path中的參數(shù)
在路由中使用通配符時,對應(yīng)的通配符就會成為URL Path參數(shù),調(diào)用gin.Context的Param()方法可以獲取Path參數(shù):
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()
}
運行后發(fā)起請求:
$ curl http://localhost:8080/user/100 你的請求id:100
獲取URL Query中的參數(shù)
gin.Context對象提供了以下幾個主要方法用于獲取Query參數(shù):
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", "男")
//數(shù)組
habits := ctx.QueryArray("habits")
//map
works := ctx.QueryMap("works")
fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works)
})
?
engine.Run()
}
運行后發(fā)起請求:
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中的參數(shù)
對于通過HTTP Body傳上來的參數(shù),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", "男")
//數(shù)組
habits := ctx.PostFormArray("habits")
//map
works := ctx.PostFormMap("works")
fmt.Printf("%s,%s,%s,%s\n", name, gender, habits, works)
})
?
engine.Run()
}
綁定請求參數(shù)
Gin支持綁定Header,URL Path,URL Query以及HTTP Body等不同位置數(shù)據(jù)。
綁定Header參數(shù)
綁定Header參數(shù)可以使用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()
}
運行后的請求結(jié)果:
$ curl -H "rate:300" -H "domain:music" http://localhost:8080/
{"Domain":"music","Rate":300}
綁定URL Path參數(shù)
綁定URL Path參數(shù)可以使用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參數(shù)
綁定URL Query參數(shù)可以使用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參數(shù)
我們知道HTTP Body的參數(shù)會根據(jù)不同Content-Type傳不同格式的數(shù)據(jù),Gin支持以下幾種Content-Type類型的綁定:
- JSON
- XML
- TOML
- YAML
- x-www-form-urlencoded
- multipart/form-data
注意HTTP Body的數(shù)據(jù)只在POST請求時才會進行綁定。
綁定HTTP Body參數(shù)可以用Bind()和ShouldBind()方法,這兩個方法會根據(jù)當前請求的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()
}
如果明確請求數(shù)據(jù)的類型,也可以直接調(diào)用對應(yīng)類型綁定的方法,比如確定是JSON格式數(shù)據(jù)的話,可以調(diào)用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-urlencoded和multipart/form-data,與Qurey參數(shù)一樣,結(jié)構(gòu)體需要添加form的tag:
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()
}
數(shù)據(jù)校驗
在數(shù)據(jù)綁定的時候,也可以進行數(shù)據(jù)校驗:
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()
}
運行后發(fā)起請求的結(jié)果:
$ 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
兩種方式的對比
相較于直接獲取請求參數(shù),請求數(shù)據(jù)綁定是一種更強大且優(yōu)雅的參數(shù)獲取方式,使用這種方式獲取參數(shù)有以下幾個好處:
- 直接將所有參數(shù)綁定到一個結(jié)構(gòu)體中,不需要手動一個個地獲取參數(shù)。
- 綁定后的參數(shù)會自動轉(zhuǎn)換為結(jié)構(gòu)體對應(yīng)字段的類型,不需要手動對每個參數(shù)進行數(shù)據(jù)類型轉(zhuǎn)換。
- 在進行數(shù)據(jù)綁定的同時還可以進行數(shù)據(jù)校驗。
小結(jié)
直接獲取請求參數(shù)雖然沒有綁定參數(shù)那么強大,但對于簡單的請求來說,也是夠用的,因此,我們可以根據(jù)自己的需求,選擇對應(yīng)的方式來獲取請求參數(shù)。
以上就是Go語言Gin框架獲取請求參數(shù)的兩種方式的詳細內(nèi)容,更多關(guān)于Go Gin獲取請求參數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一文搞懂Golang文件操作增刪改查功能(基礎(chǔ)篇)
這篇文章主要介紹了一文搞懂Golang文件操作增刪改查功能(基礎(chǔ)篇),Golang 可以認為是服務(wù)器開發(fā)語言發(fā)展的趨勢之一,特別是在流媒體服務(wù)器開發(fā)中,已經(jīng)占有一席之地,今天我們不聊特別深奧的機制和內(nèi)容,就來聊一聊 Golang 對于文件的基本操作2021-04-04
Go調(diào)用C++動態(tài)庫實現(xiàn)車牌識別的示例代碼
本文主要介紹了如何利用C++中Opencv、TensorRT等庫編譯出動態(tài)庫供Go調(diào)用,再寫個簡單的api對上傳的車輛圖片進行車牌識別,文中通過代碼示例給大家介紹的非常詳細,需要的朋友可以參考下2023-12-12
使用Golang的channel交叉打印兩個數(shù)組的操作
這篇文章主要介紹了使用Golang的channel交叉打印兩個數(shù)組的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
golang中的io.ReadCloser與ioutil.NopCloser使用
這篇文章主要介紹了golang中的io.ReadCloser與ioutil.NopCloser使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
Air實現(xiàn)Go程序?qū)崟r熱重載使用過程解析示例
這篇文章主要為大家介紹了Air實現(xiàn)Go程序?qū)崟r熱重載使用過程解析示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-04-04

