这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记
获取参数
querystring 参数
querystring指的是URL中?后面携带的参数,例如:/user/search?username=小王子&address=沙河。
获取请求的querystring参数的方法有:gin.Query()、gin.DefaultQuery()、gin.GetQuery()。
示例:
func main() {
r := gin.Default()
r.GET("/user/search", func(c *gin.Context) {
// 获取浏览器请求中携带的 querystring 参数
// 1.Query: 参数为key,返回用户输入的值
//username := c.Query("username")
address := c.Query("address")
// 2.DefaultQuery:若querystring的key不是username,则返回默认值“游客”
//username := c.DefaultQuery("username", "游客")
// 3. GetQuery:返回两个值,若querystring的key不是username,则第二个返回值为false
username, ok := c.GetQuery("username")
if !ok {
username = "游客"
}
// 获取到参数后使用JSON格式输出参数
c.JSON(http.StatusOK, gin.H{
"username": username,
"address": address,
})
})
r.Run(":8080")
}
测试:
form 参数
当前端请求的数据通过form表单提交时,获取请求数据的方法:
gin.PostForm()gin.DefaultPostForm()
示例:
login.html 页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>form</title>
</head>
<body>
<form action="/use/login" method="post">
<div>
<label for="username">username:</label>
<input type="text" name="username" id="username">
</div>
<div>
<label for="password">password:</label>
<input type="text" name="password" id="password">
</div>
<div>
<input type="submit" value="Login">
</div>
</form>
</body>
</html>
index.html 页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h1>Hello, {{ .username }}</h1>
<p>Your password: {{ .password }}</p>
</body>
</html>
go 程序:
func main() {
r := gin.Default()
// 解析html
r.LoadHTMLFiles("./login.html", "./index.html")
// GET /login 返回login.html页面
r.GET("/login", func(c *gin.Context) {
c.HTML(http.StatusOK, "login.html", nil)
})
// POST /login 从form表单获取的数据,返回到index.html中渲染
r.POST("/login", func(c *gin.Context) {
// 1.PostForm:参数key对应html页面的name值
username := c.PostForm("username")
password := c.PostForm("password")
// DefaultPostForm取不到值时会返回指定的默认值
//username := c.DefaultPostForm("username", "游客")
c.HTML(http.StatusOK, "index.html", gin.H{
"username": username,
"password": password,
})
})
r.Run(":8080")
}
启动项目,访问/login:
json 参数
当前端请求的数据通过 JSON 提交时,例如向 /json 发送一个POST请求,则获取请求参数的方式如下:
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)
})
更便利的获取请求参数的方式,参见下面 参数绑定 。
path 参数
请求的参数通过URL路径传递,例如:/user/search/杨超越/18。 获取请求URL路径中的参数的方法:
gin.Param()
需要在GET请求路径中使用 : 表示要传入的参数名。
示例:
func main() {
r := gin.Default()
r.GET("/user/search/:username/:age", func(c *gin.Context) {
username := c.Param("username")
age := c.Param("age")
c.JSON(http.StatusOK, gin.H{
"username": username,
"age": age,
})
})
r.Run(":8080")
}
测试:
参数绑定
为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中QueryString、form表单、JSON、XML等参数到结构体中。
ShouldBind会按照下面的顺序解析请求中的数据完成绑定:
- 如果是
GET请求,只使用Form绑定引擎(querystring)。 - 如果是
POST请求,首先检查content-type是否为JSON或XML,然后再使用Form(form-data)。
下面的示例代码演示了.ShouldBind()强大的功能,它能够基于请求自动提取JSON、form表单和QueryString类型的数据,并把值绑定到指定的结构体对象。
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
//User Binding from JSON and form
type User struct {
Username string `json:"username" form:"username"`
Password string `json:"password" form:"password"`
}
func main() {
r := gin.Default()
// 绑定JSON ({"username": "AruNi", "password": "123456"})
r.POST("/loginJSON", func(c *gin.Context) {
var user User
// ShouldBind()会根据请求的Content-Type自行选择绑定器
if err := c.ShouldBind(&user); err == nil {
c.JSON(http.StatusOK, gin.H{
"username": user.Username,
"password": user.Password,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
// 绑定form表单 (username=AruNi&&password=123456)
r.POST("/loginForm", func(c *gin.Context) {
var user User
// ShouldBind()会根据请求的Content-Type自行选择绑定器
if err := c.ShouldBind(&user); err == nil {
c.JSON(http.StatusOK, gin.H{
"username": user.Username,
"password": user.Password,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
// 绑定querystring (/loginQuery?username=AruNi&&password=123456)
r.GET("/loginQuery", func(c *gin.Context) {
var user User
// ShouldBind()会根据请求的Content-Type自行选择绑定器
if err := c.ShouldBind(&user); err == nil {
c.JSON(http.StatusOK, gin.H{
"username": user.Username,
"password": user.Password,
})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
r.Run(":8080")
}
JSON 测试:
form 表单测试:
querystring 测试: