Gin 中间件 | 青训营

111 阅读2分钟

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 继续执行剩下的语句。


在路由分组中配置中间件