1. 程式人生 > 其它 >Gin框架系列之請求引數處理

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")
}