一、GET 请求传值

GET请求就是在 URL 中携带的参数,如

1
http://127.0.0.1:8080/?username=admin&passwd=12345&page=10

就传递了usernamepasswordpage三个参数

1
2
3
4
5
6
7
8
9
10
11
r.GET("/", func(c *gin.Context) {
username := c.Query("username")
passwd := c.Query("passwd")
page := c.DefaultQuery("page", "1")

c.JSON(http.StatusOK, gin.H{
"username": username,
"passwd": passwd,
"page": page,
})
})

使用c.Query()接收数据,而使用c.DefaultQuery()还能指定默认值

二、POST 请求传值,获取 form 表单数据

我们现在需要配置两个路由,其中addUser.html需要写模板创建一个表单并向doAddUser.html发送POST请求,而doAddUser.html则只需接收信息并打印出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="doAddUser.html" method="post">
用户名:<input type="text" name="username" /><br>
密码:<input type="password" name="password" /><br>
<input type="submit" value="提交">
</form>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
r.GET("addUser.html", func(c *gin.Context) {
c.HTML(http.StatusOK, "addUser.html", gin.H{})
})

// POST 传值
r.POST("doAddUser.html", func(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
age := c.DefaultPostForm("age", "18")

c.JSON(http.StatusOK, gin.H{
"username": username,
"password": password,
"age": age,
})
})

与 GET 类似也有两个函数,使用c.PostForm()接收数据,而c.DefaultPostForm()能指定默认值

三、动态路由传值

假设在/user目录下为每一个用户以 uid 分别提供页面,如/user/1/user/2/user/3

1
2
3
4
r.GET("/user/:uid", func(c *gin.Context) {
uid := c.Param("uid")
c.String(http.StatusOK, "这是第 %s 位用户的页面", uid)
})

四、解析 JSON 和 XML 数据

在 API 的开发中,我们经常会用到 JSON 或 XML 来作为数据交互的格式,这个时候我们
可以使用 GetRawData()+Unmarshal() 获取数据

1
2
3
4
5
<?xml version="1.0" encoding="UTF-8"?>
<article>
<content type="string">我是张三</content>
<title type="string">张三</title>
</article>
1
2
3
4
type Article struct {
Title string `xml:"title" json:"title"` // tag 不要忘
Content string `xml:"content" json:"content"`
}
1
2
3
4
5
6
7
8
9
10
11
12
r.POST("/xml", func(c *gin.Context) {
article := &Article{}
xmlSliceData, _ := c.GetRawData()
// GetRawData 返回的是切片,再用 Unmarshal 转换至结构体
if err := xml.Unmarshal(xmlSliceData, &article); err == nil {
c.JSON(http.StatusOK, article)
} else {
c.JSON(http.StatusBadRequest, gin.H{
"err": err.Error(),
})
}
})

五、绑定数据到结构体

更好的选择是使用基于请求的 Content-Type 识别请求数据类型并利用反射机制自动提取请求中QueryString、 form 表单、JSON、 XML等参数到结构体中

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

1
2
3
4
type UserInfo struct {
Username string `form:"username" json:"user"` // tag 不要忘
Password string `form:"password" json:"password"`
}
1
2
3
4
5
6
7
8
9
10
r.POST("doAddUser.html", func(c *gin.Context) {
user := &UserInfo{}
if err := c.ShouldBind(&user); err == nil { //解析到 user 结构体中
c.JSON(http.StatusOK, user)
} else {
c.JSON(http.StatusOK, gin.H{
"err": err.Error(),
})
}
})