这是我参与「第五届青训营 」伴学笔记创作活动的第 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) string或func (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识别请求数据类型并利用反射机制自动提取请求中QueryString、form表单、JSON、XML等参数到结构体中。下面的示例代码将演示.ShouldBind()强大的功能,它能够自动提取基于querystring、form、json、path的参数:
// 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")
}