Gin框架系列之請求引數處理
一、GET請求處理
(一)路徑引數
對於類似這樣的請求:http://127.0.0.1:8080/index/12,那麼如何獲取最後路徑中12的值呢?
package main import ( "fmt" "github.com/gin-gonic/gin" "net/http" ) func Index(ctx *gin.Context) { id := ctx.Param("id") fmt.Println(id) ctx.String(http.StatusOK, "success!") } func main() { router := gin.Default()// 路徑引數獲取,如:http://127.0.0.1:8080/index/12,獲取12 router.GET("/index/:id", Index) router.Run(":8080") }
在掛載路由時需要通過":"來進行匹配,然後在檢視函式中通過ctx.Param方法獲取。
(二)查詢引數
對於類似這樣的請求:http://127.0.0.1:8080/index1?id=12,那麼如何獲取最後路徑中12的值呢?
1、ctx.Query
傳參:http://127.0.0.1:8080/index1?id=12
路由:router.GET("/index1", Index1)
檢視函式獲取:ctx.Query("id")
2、ctx.DefaultQuery
傳參:http://127.0.0.1:8080/index2
路由:router.GET("/index2", Index2)
檢視函式獲取:ctx.DefaultQuery("id", "0")
如果沒有獲取到id,就得到預設值0.
3、ctx.QueryArray
傳參:http://127.0.0.1:8080/index3?id=1,2,3,4,5
路由:router.GET("/index3", Index3)
檢視函式獲取:ctx.QueryArray("id")
4、ctx.QueryMap
傳參:http://127.0.0.1:8080/index4?user[name]=%22lily%22&user[age]=15
路由:router.GET("/index4", Index4)
檢視函式獲取:ctx.QueryMap("user")
(三)例項
package main import ( "fmt" "github.com/gin-gonic/gin" "net/http" ) func Index(ctx *gin.Context) { id := ctx.Param("id") fmt.Println(id) ctx.String(http.StatusOK, "success!") } func Index1(ctx *gin.Context) { id := ctx.Query("id") fmt.Println(id) // 12 ctx.String(http.StatusOK, "success!") } func Index2(ctx *gin.Context) { id := ctx.DefaultQuery("id", "0") fmt.Println(id) // 0 ctx.String(http.StatusOK, "success!") } func Index3(ctx *gin.Context) { idList := ctx.QueryArray("id") fmt.Println(idList) // [1,2,3,4,5] ctx.String(http.StatusOK, "success!") } func Index4(ctx *gin.Context) { user := ctx.QueryMap("user") fmt.Println(user) // map[age:15 name:"lily"] ctx.String(http.StatusOK, "success!") } func main() { router := gin.Default() // 路徑引數獲取,如:http://127.0.0.1:8080/index/12,獲取12 router.GET("/index/:id", Index) // 查詢引數獲取,如:http://127.0.0.1:8080/index?id=12,獲取12 router.GET("/index1", Index1) router.GET("/index2", Index2) router.GET("/index3", Index3) router.GET("/index4", Index4) router.Run(":8080") }
二、POST請求處理
(一) 普通方式提交表單
1、ctx.PostForm
- 表單
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/post_index" method="post"> <p>使用者名稱:<input type="text" name="username"></p> <p>密 碼:<input type="password" name="password"></p> <p><input type="submit"></p> </form> </body> </html>
- 後臺處理
... func PostIndex(ctx *gin.Context) { username := ctx.PostForm("username") password := ctx.PostForm("password") fmt.Printf("使用者名稱:%s, 密碼:%s", username, password) ctx.String(http.StatusOK, "提交成功!") } ...
2、ctx.PostFormMap
- 表單
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> </body> </html><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/post_index1" method="post"> <p>使用者名稱:<input type="text" name="user[username]"></p> <p>密 碼:<input type="password" name="user[password]"></p> <p><input type="submit"></p> </form> </body> </html>
- 後臺處理
... func PostIndex1(ctx *gin.Context) { userMap := ctx.PostFormMap("user") fmt.Println(userMap) ctx.String(http.StatusOK, "提交成功!") } ...
3、ctx.DefaultPostForm、ctx.PostFormArray
- 表單
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/post_index2" method="post"> <p>使用者名稱:<input type="text" name="username"></p> <p>密 碼:<input type="password" name="password"></p> <p>愛 好: 讀書<input type="checkbox" name="hobby" value="1"> 看電影<input type="checkbox" name="hobby" value="2"> 音樂<input type="checkbox" name="hobby" value="3"> </p> <p><input type="submit"></p> </form> </body> </html>
- 後臺處理
... func PostIndex2(ctx *gin.Context) { username := ctx.PostForm("username") password := ctx.PostForm("password") age := ctx.DefaultPostForm("age", "0") hobby := ctx.PostFormArray("hobby") fmt.Printf("使用者名稱:%s, 密碼:%s, 年齡:%s, 愛好:%s", username, password, age, hobby) ctx.String(http.StatusOK, "提交成功!") } ...
4、後臺主要檔案
package main import ( "fmt" "github.com/gin-gonic/gin" "net/http" ) func GetIndex(ctx *gin.Context) { ctx.HTML(http.StatusOK, "index.html", nil) } func PostIndex(ctx *gin.Context) { username := ctx.PostForm("username") password := ctx.PostForm("password") fmt.Printf("使用者名稱:%s, 密碼:%s", username, password) ctx.String(http.StatusOK, "提交成功!") } func GetIndex1(ctx *gin.Context) { ctx.HTML(http.StatusOK, "index1.html", nil) } func PostIndex1(ctx *gin.Context) { userMap := ctx.PostFormMap("user") fmt.Println(userMap) ctx.String(http.StatusOK, "提交成功!") } func GetIndex2(ctx *gin.Context) { ctx.HTML(http.StatusOK, "index2.html", nil) } func PostIndex2(ctx *gin.Context) { username := ctx.PostForm("username") password := ctx.PostForm("password") age := ctx.DefaultPostForm("age", "0") hobby := ctx.PostFormArray("hobby") fmt.Printf("使用者名稱:%s, 密碼:%s, 年齡:%s, 愛好:%s", username, password, age, hobby) ctx.String(http.StatusOK, "提交成功!") } func main() { router := gin.Default() router.LoadHTMLGlob("template/*") // ctx.PostForm router.GET("/get_index", GetIndex) router.POST("/post_index", PostIndex) // ctx.PostFormMap router.GET("/get_index1", GetIndex1) router.POST("/post_index1", PostIndex1) // ctx.DefaultPostForm、ctx.PostFormArray router.GET("/get_index2", GetIndex2) router.POST("/post_index2", PostIndex2) router.Run(":8080") }
(二)Ajax方式提交表單
ajax的後臺處理邏輯與普通的表單的提交的處理方式基本相同,只不過在返回的時候需要返回json資料,前臺使用回撥函式進行處理。
- 前臺
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/static/js/jquery-3.6.0.js"></script> </head> <body> <form> <p>使用者名稱:<input id="username" type="text"></p> <p>密碼:<input id="password" type="password"></p> <p><input type="button" value="提交" id="btn_submit"></p> </form> <script> var btn = document.getElementById("btn_submit") btn.onclick = function (ev) { var username = document.getElementById("username").value var password = document.getElementById("password").value $.ajax({ url: '/post_index', type: 'POST', data: { username: username, password: password }, success: function (data) { alert(data) // 響應成功的回撥函式 }, fail: function (data) { } }) } </script> </body> </html>
- 後臺
package main import ( "fmt" "github.com/gin-gonic/gin" "net/http" ) func GetIndex(ctx *gin.Context) { ctx.HTML(http.StatusOK, "index.html", nil) } func PostIndex(ctx *gin.Context) { username := ctx.PostForm("username") password := ctx.PostForm("password") fmt.Println(username, password) data := map[string]interface{}{ "code": 2000, "message": "成功", } ctx.JSON(http.StatusOK, data) } func main() { router := gin.Default() router.LoadHTMLGlob("template/*") router.Static("/static", "static") router.GET("/get_index", GetIndex) router.POST("/post_index", PostIndex) router.Run(":8080") }
三、引數繫結
無論時get請求的引數還是post請求的請求體,在後臺都需要通過對應的方法來獲取對應引數的值,那麼有沒有一種方式能夠讓我們定義好請求資料的格式,然後自動進行獲取,這裡可以通過引數繫結的方式來進行處理。它能夠基於請求自動提取JSON、form表單和QueryString型別的資料,並把值繫結到指定的結構體物件。
這裡以get請求的查詢引數為例:
- 請求格式
http://127.0.0.1:8080/index?username=%22llkk%22&password=%22123%22
- 後臺處理
package main import ( "fmt" "github.com/gin-gonic/gin" "net/http" ) type User struct { Username string `form:"username" json:"username"` Password string `form:"password" json:"password"` } func Index(ctx *gin.Context) { var user User err := ctx.ShouldBind(&user) fmt.Println(err) fmt.Println(user.Username, user.Password) // "llkk" "123" ctx.String(http.StatusOK, "success") } func main() { router := gin.Default() router.GET("/index", Index) router.Run(":8080") }