本文作者:杰哥的技术杂货铺[1]
一、获取 query 参数
query 指的是 URL ? 后面携带的参数,例如 user/info?username=张三&password=123。获取请求的 query 参数的方法如下:
- 当使用
DefaultQuery
时,如果没有获取到浏览器输入的 username,则返回设置 defaultValue
username := ctx.DefaultQuery("username", "杰哥的技术杂货铺")
- 当使用
Query
时,如果没有获取到浏览器输入的 password,则默认返回""空串
password := ctx.Query("password")
完整示例如下
浏览器输入为:
代码语言:javascript复制http://127.0.0.1:8000/user/info?username=张三&password=123456
服务端返回为:
代码语言:javascript复制{"message":"success","password":"123456","username":"张三"}
后端处理逻辑如下:
代码语言:javascript复制package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
//设置gin模式
gin.SetMode(gin.ReleaseMode)
//创建一个新的路由引擎
r := gin.New()
// GET:请求方式; /user/info:请求的路径
r.GET("/user/info", func(ctx *gin.Context) {
// 当使用DefaultQuery时,如果没有获取到浏览器输入的username,则返回设置defaultValue给username
username := ctx.DefaultQuery("username", "杰哥的技术杂货铺")
// 当使用Query时,如果没有获取到浏览器输入的password,则默认返回""空串
password := ctx.Query("password")
// 返回json给浏览器
ctx.JSON(http.StatusOK, gin.H{
"message": "success",
"username": username,
"password": password,
})
})
// 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
r.Run(":8000")
}
注:一般使用 Query 方法
二、获取 form 表单参数
当前端请求的数据通过 form 表单提交时,例如向/user/info 发送一个 POST 请求,获取请求数据的方式如下:
完整示例如下
后端处理逻辑如下:
代码语言:javascript复制package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
//设置gin模式
gin.SetMode(gin.ReleaseMode)
//创建一个新的路由引擎
r := gin.New()
// POST:请求方式; /user/info:请求的路径
r.POST("/user/info", func(ctx *gin.Context) {
//提交单个表单数据时
//如果没有在请求中获取到表单参数,则返回默认值"张三"
username := ctx.DefaultPostForm("username", "张三")
//如果没有在请求中获取到表单参宿,则返回""空串
password := ctx.PostForm("password")
//提交复选框多个数据时
info := ctx.PostFormArray("info")
// 输出json结果给调用方
ctx.JSON(http.StatusOK, gin.H{
"message": "success",
"username": username,
"password": password,
"info": info,
})
})
// 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
r.Run(":8000")
}
注:一般使用 PostForm 方法
三、获取 JSON 参数
当前端请求的数据通过 json 提交时,例如向/user/info 发送一个 POST 请求,则获取请求参数的方式如下:
- 使用 postman 配置 json 请求如下:
72vl8g
- 后端处理逻辑如下:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
type User struct {
// 如果想要指定返回的json为其他别名,则可以使用`json:"username"`定义json格式的别名
UserName string `json:"username"`
PassWord string `json:"password"`
}
func main() {
//设置gin模式
gin.SetMode(gin.ReleaseMode)
//创建一个新的路由引擎
r := gin.New()
// POST:请求方式; /user/info:请求的路径
r.POST("/user/info", func(ctx *gin.Context) {
// 创建一个json结构体实例并与请求json参数绑定
userBody := &User{}
err := ctx.BindJSON(&userBody)
// 判断json请求数据结构与定义的结构体有没有绑定成功
if err != nil {
ctx.JSON(200, gin.H{
"err_no": 400,
"message": "Post Data Err",
})
} else {
ctx.JSON(http.StatusOK, gin.H{
"username": userBody.UserName,
"password": userBody.PassWord,
})
}
})
// 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
r.Run(":8080")
}
- 返回结果如下所示:
72vgVx
四、获取 path 参数
请求的参数通过 URL 路径传递,例如/user/info/张三/123456。获取请求 URL 路径中的参数的方式如下。
- 浏览器输入为:
127.0.0.1:8080/user/info/张三/123456
- 后端处理逻辑如下:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
//设置gin模式
gin.SetMode(gin.ReleaseMode)
//创建一个新的路由引擎
r := gin.New()
// GET:请求方式; /user/info:请求的路径
r.GET("/user/info/:username/:password", func(ctx *gin.Context) {
// 如果没有获取到相关路径参数,则返回""空串
username := ctx.Param("username")
password := ctx.Param("password")
//返回结果给调用方
ctx.JSON(http.StatusOK, gin.H{
"message": "success",
"username": username,
"password": password,
})
})
// 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
r.Run(":8080")
}
- 返回结果如下:
{"message":"success","password":"123456","username":"张三"}
注意如下请求路由定义方式是不合法的,如果想要定义两个类似的请求路由,可以加入版本号进行区分,如/user/v1/info/——>/user/v2/info/,版本号从 v1 到 v2。
错误写法:
代码语言:javascript复制// GET:请求方式; /hello:请求的路径
r.GET("/user/info/:username/:password", func(c *gin.Context) {
})
r.GET("/user/info/:username/:password", func(c *gin.Context) {
})
正确写法:
代码语言:javascript复制r.GET("/user/v1/info/:username/:password", func(ctx *gin.Context) {
// 如果没有获取到相关路径参数,则返回""空串
username := ctx.Param("username")
password := ctx.Param("password")
//返回结果给调用方
ctx.JSON(http.StatusOK, gin.H{
"message": "success",
"username": username,
"password": password,
})
})
r.GET("/user/v2/info/:username/:address", func(ctx *gin.Context) {
// 如果没有获取到相关路径参数,则返回""空串
username := ctx.Param("username")
address := ctx.Param("address")
//返回结果给调用方
ctx.JSON(http.StatusOK, gin.H{
"message": "success",
"username": username,
"address": address,
})
})
五、参数绑定
为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的 Content-Type 识别请求数据类型并利用反射机制自动提取请求中 QueryString、form 表单、JSON、XML 等参数到结构体中。下面的示例代码演示了.ShouldBind()强大的功能,它能够基于请求自动提取 JSON、form 表单和 QueryString 类型的数据,并把值绑定到指定的结构体对象。
- 通过 query 方式请求,此时输入 url,不需要其他配置:
7RnXxs
- 通过 json 方式请求,输入 url,输入 json body,输入 Content-Type=application/json。
7RKi0P
- 后端处理逻辑如下:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
// Login Binding from JSON
type Login struct {
UserName string `form:"username" json:"username" binding:"required"`
Password string `form:"password" json:"password" binding:"required"`
}
func main() {
//设置gin模式
gin.SetMode(gin.ReleaseMode)
//创建一个新的路由引擎
r := gin.New()
// 绑定JSON的示例 ({"username": "张三", "password": "123456"})
r.POST("/loginJSON", func(ctx *gin.Context) {
// 创建一个结构体类型实例
login := Login{}
if err := ctx.ShouldBind(&login); err == nil {
ctx.JSON(http.StatusOK, gin.H{
"message": "login with json query",
"username": login.UserName,
"password": login.Password,
})
} else {
ctx.JSON(http.StatusBadRequest, gin.H{
"err_no": err.Error(),
})
}
})
// 绑定form表单示例 (user=张三&password=123456)
r.POST("/loginForm", func(ctx *gin.Context) {
login := Login{}
// ShouldBind()会根据请求的Content-Type自行选择绑定器
if err := ctx.ShouldBind(&login); err == nil {
ctx.JSON(http.StatusOK, gin.H{
"message": "login with form query",
"username": login.UserName,
"password": login.Password,
})
} else {
ctx.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
}
})
// 绑定QueryString示例 (/loginQuery?user=张三&password=123456)
r.GET("/loginQuery", func(ctx *gin.Context) {
login := Login{}
// ShouldBind()会根据请求的Content-Type自行选择绑定器
if err := ctx.ShouldBind(&login); err == nil {
ctx.JSON(http.StatusOK, gin.H{
"message": "login with querystring query",
"username": login.UserName,
"password": login.Password,
})
} else {
ctx.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
}
})
// 启动HTTP服务,默认在8080端口启动服务,也可以设置为其他端口如8000
r.Run(":8080")
}
ShouldBind 会按照下面的顺序解析请求中的数据完成绑定:
- 如果是 GET 请求,只使用 Form 绑定引擎(query)。
- 如果是 POST 请求,首先检查 content-type 是否为 JSON 或 XML,然后再使用 Form(form-data)。
至此,我们学会了 gin 框架如何获取请求参数的方式。
本系列文章:
从零开发区块链应用(一)--golang 配置文件管理工具 viper[2]
从零开发区块链应用(二)--mysql 安装及数据库表的安装创建[3]
从零开发区块链应用(三)--mysql 初始化及 gorm 框架使用[4]
从零开发区块链应用(四)--自定义业务错误信息[5]
从零开发区块链应用(五)--golang 网络请求[6]
从零开发区块链应用(六)--gin 框架使用[7]
从零开发区块链应用(七)--gin 框架参数获取[8]
从零开发区块链应用(八)--结构体初识[9]
从零开发区块链应用(九)--区块链结构体创建[10]
从零开发区块链应用(十)--golang 协程使用[11]
从零开发区块链应用(十一)--以太坊地址生成[12]
参考资料
[1]
杰哥的技术杂货铺: https://learnblockchain.cn/people/3835
[2]
从零开发区块链应用(一)--golang配置文件管理工具viper: https://learnblockchain.cn/article/3446
[3]
从零开发区块链应用(二)--mysql安装及数据库表的安装创建: https://learnblockchain.cn/article/3447
[4]
从零开发区块链应用(三)--mysql初始化及gorm框架使用: https://learnblockchain.cn/article/3448
[5]
从零开发区块链应用(四)--自定义业务错误信息: https://learnblockchain.cn/article/3449
[6]
从零开发区块链应用(五)--golang网络请求: https://learnblockchain.cn/article/3457
[7]
从零开发区块链应用(六)--gin框架使用: https://learnblockchain.cn/article/3480
[8]
从零开发区块链应用(七)--gin框架参数获取: https://learnblockchain.cn/article/3481
[9]
从零开发区块链应用(八)--结构体初识: https://learnblockchain.cn/article/3482
[10]
从零开发区块链应用(九)--区块链结构体创建: https://learnblockchain.cn/article/3483
[11]
从零开发区块链应用(十)--golang协程使用: https://learnblockchain.cn/article/3484
[12]
从零开发区块链应用(十一)--以太坊地址生成: https://learnblockchain.cn/article/3485