本博客介绍使用gin框架完成基础的数据解析与绑定功能,以及列举出一些比较容易踩的坑。主要内容包括:json数据解析与绑定,表单数据解析与绑定,url数据解析与绑定
先看官方文档中的源代码:
// 定义接收数据的结构体
type Login struct {
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}
func main() {
r := gin.Default()
// JSON绑定
r.POST("loginJSON", func(c *gin.Context) {
var json Login
// 将request的body中的数据,自动按照json格式解析到结构体
if err := c.ShouldBindJSON(&json); err != nil {
// 返回错误信息
// gin.H封装了生成json数据的工具
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 判断用户名密码是否正确
if json.User != "root" || json.Pssword != "admin" {
c.JSON(http.StatusBadRequest, gin.H{"status": "304"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "200"})
})
r.Run(":8000")
}
这是一个简单的获取json中的账号密码,并进行验证的例子。从该例子中可以看出:
于是,我们可以:
c *gin.Context
作为方程的参数下面用一个比较完整的程序片段来阐述具体用法:
service结构体中的数据
type CreateTeamService struct {
model.TeamRepositoryInterface // 声明了具体操作数据库创建团队的接口
Name string `form:"name" json:"name" binding:"required"`
GroupLeaderID int `form:"group_leader_id" json:"group_leader_id" binding:"required"`
ClassID int `form:"class_id" json:"class_id" binding:"required"`
}
post方法响应请求
// 创建团队
v1.POST("team/create", api.CreateTeam)
json数据解析与绑定具体函数
func CreateTeam(c *gin.Context) { // 该函数与CreateTeamService服务在不同的文件中
var service service.CreateTeamService
if err := c.ShouldBind(&service); err == nil {
// 实例化接口
service.TeamRepositoryInterface = &model.Repo
res := service.CreateTeam()
c.JSON(http.StatusOK, res)
} else {
c.JSON(http.StatusOK, ErrorResponse(err))
}
}
可以看出,大致过程与上述官方文档中的用例一致。
具体代码与json数据解析与绑定几乎完全一致,不同处仅仅在于将ShouldBindJSON()
方法换成了Bind()
方法。
这也是gin框架的强大之处,即面对不同的前端数据有统一的代码处理方法。其本质上,还是将表单数据中每个数据的key值与结构中的数据一一对应。
表单结构示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="http://localhost:8000/loginForm" method="post" enctype="application/x-www-form-urlencoded">
用户名<input type="text" name="username"><br>
密码<input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
结构体示例
type Login struct {
// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}
具体代码与上述两种方式大致相同,同样地,需要将ShouldBindJSON()
方法换成ShouldBindUri
方法。
除此之外,需要注意获取api参数的方法,在此仅介绍最简单的一种方法:
获取api参数代码
(测试url:localhost:8080/user/乌鸡/805376577.com
)
r.GET("/user/:name/*action", func(c *gin.Context) {
name := c.Param("name")
action := c.Param("action")
//截取/
action = strings.Trim(action, "/")
c.String(http.StatusOK, name+" is "+action)
})
输出结果:乌鸡 is 805376577.com
http.StatusOK
替代200
gin框架给代码的编写带来了诸多方便,不仅代码简单友好,并且在程序出错的情况下也可以通过报错快速找到解决措施,因为gin的报错都很详细,我推荐使用go语言可以多多使用gin框架。
虽然网上gin的官方文档都介绍的比较详细,但是关于gin的个人教程以及问答帖子在国内的数量比较少,所以有时候出了问题比较难在网上直接找到解决方法。好在gin语法简单,只要有一定编程基础,应该都能够独立解决大部分问题。
http://www.topgoer.com/gin框架/gin路由/api参数.html
原文:https://www.cnblogs.com/fuguidelaoniu/p/14942966.html