获取querystring
querystring是URL里 ?后面带的参数内容。
例:https://b.com?user=me&pwd=123
得到 user=me 和 pwd=123
func main() {
//Default返回一个默认的路由引擎
r := gin.Default()
r.GET("/test", func(c *gin.Context) {
//设置默认值
user := c.DefaultQuery("username", "test")
//获取url里的user参数
user = c.Query("user")
//输出json结果给调用方
c.JSON(200, gin.H{
"message": "ok",
"username": user,
})
})
r.Run(":8080")
}
获取form参数
当前端请求的数据通过form表单提交时,例如发送一个POST请求
func main() {
//Default返回一个默认的路由引擎
r := gin.Default()
r.POST("/test", func(c *gin.Context) {
//设置默认值
user := c.DefaultPostForm("username", "test")
//获取url里的user参数
user = c.PostForm("user")
//输出json结果给调用方
c.JSON(200, gin.H{
"message": "ok",
"username": user,
})
})
r.Run(":8080")
}
获取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路径传递,例如: go
/test/名字/密码
获取请求URL路径中的参数
func main() {
//Default返回一个默认的路由引擎
r := gin.Default()
r.GET("/test/:user/:pwd", func(c *gin.Context) {
username := c.Param("user")
password := c.Param("pwd")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"password": password,
})
})
r.Run(":8080")
}
参数绑定
为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的
Content-Type
识别请求数据类型并利用反射机制自动提取请求中QueryString
、form表单
、JSON
、XML
等参数到结构体中。 下面的示例代码演示了.ShouldBind()
强大的功能,它能够基于请求自动提取JSON
、form表单
和QueryString
类型的数据,并把值绑定到指定的结构体对象。
// 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:8080
router.Run(":8080")
}
ShouldBind
会按照下面的顺序解析请求中的数据完成绑定:
- 如果是
GET
请求,只使用Form
绑定引擎(query
)。 - 如果是
POST
请求,首先检查content-type
是否为JSON
或XML
,然后再使用Form
(form-data
)
文件上传
func main() {
router := gin.Default()
// 处理multipart forms提交文件时默认的内存限制是32 MiB
// 可以通过下面的方式修改
// router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// 单个文件
file, err := c.FormFile("f1")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
return
}
log.Println(file.Filename)
dst := fmt.Sprintf("C:/tmp/%s", file.Filename)
// 上传文件到指定的目录
c.SaveUploadedFile(file, dst)
c.JSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("'%s' uploaded!", file.Filename),
})
// Multipart form 多文件上传
// form, _ := c.MultipartForm()
// files := form.File["file"]
// for index, file := range files {
// log.Println(file.Filename)
// dst := fmt.Sprintf("C:/tmp/%s_%d", file.Filename, index)
// // 上传文件到指定的目录
// c.SaveUploadedFile(file, dst)
// }
// c.JSON(http.StatusOK, gin.H{
// "message": fmt.Sprintf("%d files uploaded!", len(files)),
// })
// })
})
router.Run()
}