gin 参数绑定 | 青训营笔记

105 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天 为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的 Content-Type 识别请求数据类型并利用反射机制自动提取请求中 QueryStringform表单JSONXML 等参数到结构体中。

bindJson only can bind json

下面的示例代码演示了 .ShouldBind() 强大的功能,它能够基于请求自动提取 JSONform表单QueryString 类型的数据,并把值绑定到指定的结构体对象。

[!note]- 结构体中tag 标签的作用, 不太正确 User string: 不加 tag, 就必须用结构体的名字 image.png User string form:"user" binding:"required", 需要有 binding 有 tag 可以用该类型的别名

image.png image.png


package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

type UserInfo struct {
	Username string `form:"username" json:"user"`
	Password string `form:"password" json:"pwd" `
}

func main() {
	r := gin.Default()
	r.LoadHTMLFiles("./index.html")
	r.GET("/index", func(c *gin.Context) {
		c.HTML(200, "index.html", nil)
	})

	//不使用ShouldBind()函数, 打印前端传递的数据
	r.GET("/user", func(c *gin.Context) {
		c.HTML(200, "index.html", nil)
		username := c.Query("username")
		password := c.Query("password")
		u := UserInfo{
			Username: username,
			Password: password,
		}
		fmt.Printf("%#v\n", u) //%#v: 值的Go语法表示
		//测试:127.0.0.1:8080/user?username=zeefan&password=123456
		//成功得到: main.UserInfo{Username:"zeefan", Password:"123456"}

	})
	//使用ShouldBind()函数, 打印前端传递的数据
	//前端设置好了, 点击提交按钮, 会自动跳转到/form页面
	r.POST("/form", func(c *gin.Context) {
		var u UserInfo
		err := c.ShouldBind(&u)
		if err != nil {
			c.JSON(400, gin.H{
				"error": err.Error(),
			})
		} else {
			fmt.Printf("%#v\n", u)
			c.JSON(200, gin.H{
				"status": "ok",
			})
		}

	})

	//这个只能用 postman 来发送请求, 不能用浏览器,
	//因为浏览器点击提交后会自动跳转到/form页面, 会导致后面的代码无法执行
	//还有就是在网址输入, 只能发送get请求, 不能发送post请求

	//不用再次定义一个结构体了, 根据传入携带的值,会自动绑到上面的结构体上
	//测试:
	r.POST("/json", func(c *gin.Context) {
		var u UserInfo
		err := c.ShouldBind(&u)
		if err != nil {
			c.JSON(400, gin.H{
				"error": err.Error(),
			})
		} else {
			fmt.Printf("%#v\n", u)
			c.JSON(200, gin.H{
				"status": "ok",
			})
		}
	})

	r.Run()
}

测试 json image.png

main.UserInfo{Username:"user", Password:"111"}
[GIN] 2023/02/10 - 12:59:01 | 200 |    3.015792ms |       127.0.0.1 | POST     "/json"

测试 form image.png

main.UserInfo{Username:"user", Password:"111"}
[GIN] 2023/02/10 - 12:58:07 | 200 |     118.458µs |       127.0.0.1 | POST     "/form"

ShouldBind 会按照下面的顺序解析请求中的数据完成绑定:

  1. 如果是 GET 请求,只使用 Form 绑定引擎(query)。
  2. 如果是 POST 请求,首先检查 content-type 是否为 JSONXML,然后再使用 Formform-data)。