Gin 中间件
Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数 --- 中间件。
中间件 适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志等。
通俗地讲 :中间件就是*匹配路由前* 和*匹配路由完成后* 执行的一系列操作。
路由中间件
示例代码:
r.GET("/", func(a *gin.Context) {
a.String(http.StatusOK, "aaaaaa")
}, func(b *gin.Context) {
b.String(http.StatusOK, "bbbbbb")
}, func(c *gin.Context) {
c.String(http.StatusOK, "cccccc")
})
就上述代码而言,我们设置了一个路由,传入了多个 func() 函数,最后一个回调函数就是路由的一个处理程序,那么最后一个回调函数之前的所有都可以称之为中间件。
同样的,也可以不用匿名函数当参数,可以把 func() 摘出去写一个函数然后再将函数名作为参数传入。
eg:
func initMiddleware(c *gin.Context) {
fmt.Println("这是函数aaa")
c.String(http.StatusOK, "这是函数aaa-----")
}
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/*")
r.GET("/", initMiddleware, func(b *gin.Context) {
b.String(http.StatusOK, "bbbbbb")
}, func(c *gin.Context) {
c.String(http.StatusOK, "cccccc")
})
r.Run(":8000")
}
//网页显示结果为:
//这是函数aaa-----bbbbbbcccccc
参数是按顺序执行的,执行到我们自定义的函数 initMiddleware 的时候会跳到外边的函数体执行该函数,然后再继续进行下一个函数。因为 fmt.Println("这是函数aaa") 是打印在控制台,所以只能在控制台看见,网页上看不见。
ctx.Next() --- 调用该请求的剩余处理程序
中间件里加上 ctx.Next() 可以让我们再路由匹配完成后执行一些操作。
比如我们可以统计一个请求的统计时间。
接上节代码:
func initMiddleware(c *gin.Context) {
fmt.Println("这是函数aaa")
c.String(http.StatusOK, "这是函数aaa-----")
c.Next()
c.String(http.StatusOK, "-------这是Next()之后")
}
//网页显示结果为:
//这是函数aaa-----bbbbbbcccccc-------这是Next()之后
根据网页显示结果,很容易地我们可以知道 ctx.Next() 地作用 --- 从当前调用地函数中地该行开始,类似于 goto ,跳转执行接下来的所有函数,但是其他所有函数执行完毕之后还要再跳转回来执行 ctx.Next() 接下来的所有语句。
全局中间件
//用 r.Use() ,参数即为我们设置的中间件为全局中间件
r := gin.Default()
r.Use(initMiddleware)
r.GET("/aa", func(c *gin.Context) {
c.String(http.StatusOK, "asdasd")
})
用 r.Use() 不光设置括号里面的函数为全局中间件,还会进去函数执行,所以以上函数的执行顺序是:initMiddleware 里执行到 c.Next() 然后暂跳,去执行后边的函数也就是 func(c *gin.Context) ,执行完了之后回 initMiddleware 继续执行剩下的语句。