Gin框架参数获取 | 青训营笔记

384 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天

一、总览

  • GIN获取参数
    • 获取querystring参数
    • 获取form参数
    • 获取json参数
    • 获取path参数
    • 参数绑定

二、知识点详解

2.1 获取querystring参数

querystring是指在访问的URL紧接一个'?',随后以key=value的形式传递的参数,比如以下路由"../user/search?name=彭于晏&address=海淀",多个参数之间以&分隔。获取querystring参数的方法如下所示:

// 获取GET请求中的query string,并对query string进行处理
func QueryString() {
   // GET请求URL?后面的是query string参数
   // query string采用key=value的形式,多个key=value使用&连接
   // eg: */video?lessonId=1281046237&courseId=1210182958
   r := gin.Default()

   r.GET("/web", func(c *gin.Context) {
      // 获取浏览器发送的请求中携带的Query String参数
      //message := c.Query("query")
      //message := c.DefaultQuery("query", "id")
      message, ok := c.GetQueryArray("query")
      if !ok {
         // 取不到Query String
         message = []string{"帅哥美女"}
      }
      c.JSON(http.StatusOK, gin.H{
         "name": message,
      })
   })

   r.Run(":9090")
}

调用方法func (c *Context) Query(key string) (value string)func (c *Context) DefaultQuery(key, defaultValue string) stringfunc (c *Context) GetQueryArray(key string) (values []string, ok bool)获取key为"query"对应的值,随后将该值以JSON的形式返回给客户端

获取form参数

首先编写一个简单的登录界面:

<style type="text/css">
    header{
        width: 100%;/*这是设置宽,100%的意思是撑满屏幕*/
        height: 35px;/*这是设置高*/
        background-color: black;/*这是header标签的背景颜色*/
        color: white;/*这是字体颜色*/
        text-align:center;/*这是文字居中*/
        line-height: 35px;
    }
    input[type="text"],input[type="password"]{
        line-height: 48px;
        margin-top: 10px;
        width: 100%;
    }/*这是设置账号框和密码框的样式,具体的需要说的太多,
      嗯....,
      那就请你们动动你们的小手去百度搜一下叭*/
    input[type="button"]{
        width: 100%;
        margin-top: 10px;
    }
</style>

<body>
<header>login</header>
<form action="/login" method="post" novalidate autocomplete="off">
    <div>
        <input type="text" name="username" placeholder="请输入账号..." required>
        <input type="password" name="password" placeholder="请输入密码..." required>
    </div>
    <div>
        <input type="submit" value="登录"/>
    </div>
</form>
</body>

<form action="/login" method="post" novalidate autocomplete="off">其中的form表单定义了路由地址为"/login",请求方法为post,对该路由发送post请求,同时输入"username"和"password",获取数据的方式如下:

// 获取Form表单提交的参数
func Form() {
   r := gin.Default()
   r.LoadHTMLFiles("C:\Users\周俊宇\GolandProjects\gin_demo\Form\login.html", "C:\Users\周俊宇\GolandProjects\gin_demo\Form\hello.html")

   r.GET("/login", func(c *gin.Context) {
      c.HTML(http.StatusOK, "login.html", nil)
   })

   r.POST("/login", func(c *gin.Context) {
      // 使用PostForm()来获取form表单提交的数据
      //username := c.PostForm("username")
      //password := c.PostForm("password")

      // 使用DefaultPostForm()来获取form表单提交的数据
      //username := c.DefaultPostForm("username", "帅哥美女")
      //password := c.DefaultPostForm("password", "******")

      //使用GetPostForm来获取form表单提交的数据
      username, ok := c.GetPostForm("username")
      if !ok {
         username = "somebody"
      }
      password, ok := c.GetPostForm("password")
      if !ok {
         password = "somebody"
      }
      c.HTML(http.StatusOK, "hello.html", gin.H{
         "UserName": username,
         "Password": password,
      })
   })

   r.Run(":9090")
}

对应的方法类似于获取querystring参数,注意方法PostForm传入的key需要与html中form表单里的name=key相对应,如果入参key与html中的不匹配,则取不到这个值。

2.3 获取json参数

当前端向后端发送的数据以json形式提交时,我们可以定义一个map结构,使用函数GetRawData(),该方法返回类型为[]byte的数据,将该[]byte数据反序列化存储到刚刚定义的map结构中,完成json参数获取:

r.POST("/json", func(c *gin.Context) {
	// 注意:下面为了举例子方便,暂时忽略了错误处理
	b, _ := c.GetRawData()  // 从c.Request.Body读取请求数据
	// 定义map或结构体
	var m map[string]interface{}
	// 反序列化
	_ = json.Unmarshal(b, &m)

	c.JSON(http.StatusOK, m)
})

2.4 获取path参数

请求的参数还可以通过路由路径来传输,如"user/:username/:address",此时username和address目标key,我们可以获取到以path传递的username和address,可以使用func (c *Context) Param(key string) string,具体代码如下:

func main() {
	//Default返回一个默认的路由引擎
	r := gin.Default()
	r.GET("/user/search/:username/:address", func(c *gin.Context) {
		username := c.Param("username")
		address := c.Param("address")
		//输出json结果给调用方
		c.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": username,
			"address":  address,
		})
	})

	r.Run(":8080")
}

2.5 参数绑定

Gin提供了一个更加便捷、开发效率更高的方法获取参数,也就是参数绑定,我们可以基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中QueryStringform表单JSONXML等参数到结构体中。下面的示例代码将演示.ShouldBind()强大的功能,它能够自动提取基于querystringformjsonpath的参数:

// Binding from JSON
type Login struct {
	User     string `form:"user" json:"user" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

func main() {
	router := gin.Default()

	// 绑定JSON的示例 ({"user": "q1mi", "password": "123456"})
	router.POST("/loginJSON", func(c *gin.Context) {
		var login Login

		if err := c.ShouldBind(&login); err == nil {
			fmt.Printf("login info:%#v\n", login)
			c.JSON(http.StatusOK, gin.H{
				"user":     login.User,
				"password": login.Password,
			})
		} else {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
	})

	// 绑定form表单示例 (user=q1mi&password=123456)
	router.POST("/loginForm", func(c *gin.Context) {
		var login Login
		// ShouldBind()会根据请求的Content-Type自行选择绑定器
		if err := c.ShouldBind(&login); err == nil {
			c.JSON(http.StatusOK, gin.H{
				"user":     login.User,
				"password": login.Password,
			})
		} else {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
	})

	// 绑定QueryString示例 (/loginQuery?user=q1mi&password=123456)
	router.GET("/loginForm", func(c *gin.Context) {
		var login Login
		// ShouldBind()会根据请求的Content-Type自行选择绑定器
		if err := c.ShouldBind(&login); err == nil {
			c.JSON(http.StatusOK, gin.H{
				"user":     login.User,
				"password": login.Password,
			})
		} else {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
	})

	// Listen and serve on 0.0.0.0:9090
	router.Run(":9090")
}