Fork me on GitHub

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

 

posted @ 2022-04-10 11:13  iveBoy  阅读(963)  评论(0编辑  收藏  举报
TOP