这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记
初识 Gin
创建一个go mod项目
安装
go get -u github.com/gin-gonic/gin
返回值类型
- 可以使用map返回 key是string,v是interface{}
- Gin框架给我们封装好了一个叫 gin.H,其实就是一个map
- 也可以使用结构体来返回
-
- 结构体属性名必须大写开头
- 返回值就是以大写开头的属性名了,如果前端要求必须返回小写字母,那么就使用tag标签来给结构体做定制化操作
获取GET请求参数
url:localhost:9000/web?name=zhangsan
c.Query
获取POST请求参数
c.PostForm
注意:这里面的传参解析不是raw里的JSON
如果只是传单个的值要这么传入!!!!
如果传入的是JSON类型的数据,必须shouldBuild一下!!!!
获取路径参数
url:localhost:9000/web/1、localhost:9000/web/2
这和获取GET请求参数类似,使用Param()函数来获取,区别就是在路径上用 “:表示”,在java中用{}表示
r.GET("/web/:num", func(c *gin.Context) {
// 请求参数
num := c.Param("num")
data := gin.H{
"msg": "success",
"data": num,
}
c.JSON(http.StatusOK, data)
})
参数绑定
就是前端传过来的参数正好是结构体里面的属性,也就是我们常说的VO层吧。
**怎么样把前端传过来的参数匹配到结构体里面呢?
**在SpringBoot中使用的是@RequestBody注解实现的。
在Gin中,使用c.ShouldBind() 函数来完成
ShouldBind()函数底层利用的反射将数据保存到结构体中。
但是结构体有规定:
1、属性必须大写
2、要有tag标签,因为前端可能传过来的值可能和属性对不上
路由
- get、post、delete、put等方法
- 也有一个any方法,类似SpringBoot的@RequestMapping
- 没有路由的页面-----NoRoute() 可以用作404错误处理页请求
路由组
就类似于SpringBoot在类上添加一个@RequestMapping 注解,使得业务分类.
路由组也支持嵌套
xxx :=r.Group("/home")
xxx.GET()
xxx.GET()
中间件
类似SpringAOP,那些公共方法抽取出来。
中间件的定义
其实我们写的r.GET() 函数,就使用了中间件
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle(http.MethodGet, relativePath, handlers)
}
HandlerFunc,这个类型的函数就是中间件,所以中间件就是一个函数,参数类型是*gin.Context的就可以。
func m1(c *gin.Context) {
fmt.Println("m1....in")
c.Next() // 调用后序处理的函数,有点递归的意思 这里相当于一个切入
// c.About() 阻止调用后面的处理函数
// 调用完之后可以执行下面的逻辑
fmt.Println("m1....out")
}
// 一般写成闭包
func authMiddleware(doCheck bool) gin.Context {
// 一些其他操作
return func(c *gin.Context) {
// 判断是否登录
// if 登录了
// c.Next()
// else
// c.About()
}
}
这m1和authMiddleware****就是一个中间件
中间件的注册
两种方法:
- 在每个Handler的第二个参数上添加,因为第二个参数是一个 ...类型,也就是可以多参数的形式(不推荐,比较麻烦)
- 使用r.Use()全局注册
- 可以配置多个,然后在中间件的里面可以控制执行顺序。
r := gin.Default()
r.Use(m1)
路由组注册
使用路由组注册,可以实现部分拦截功能(也就是说这个功能需要一部分方法去使用,那么就使用路由组注册)
为路由组注册中间件有以下两种写法:
// 方法一
shopGroup := r.Group("/shop", StatCost())
{
shopGroup.GET("/index", func(c *gin.Context) {...})
...
}
// 方法二
shopGroup := r.Group("/shop")
shopGroup.Use(StatCost())
{
shopGroup.GET("/index", func(c *gin.Context) {...})
...
}
上下文
类似于java中的ThreadLocal。就是说在中间件里面添加上一个信息,然后在其他函数中使用
// 一般写成闭包
func authMiddleware(doCheck bool) gin.Context {
// 一些其他操作
return func(c *gin.Context) {
c.Set("mhy") // 可以通过c.Set在请求上下文中设置值,后续的处理函数能够取到该值
// 判断是否登录
// if 登录了
// c.Next()
// else
// c.About()
}
}
func aaa(c *gin.Context) {
uName,ok := c.Get("name")
// 请求参数
name := c.Query("name")
data := gin.H{
"msg": "success",
"data": name,
}
c.JSON(http.StatusOK, data)
}