Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。这个钩子函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等,即比如,如果访问一个网页的话,不管访问什么路径都需要进行登录,此时就需要为所有路径的处理函数进行统一一个中间件,Gin中的中间件必须是一个gin.HandlerFunc
类型
注册在全局,为所有路由注册
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"time"
)
func MyMiddle() gin.HandlerFunc {
return func(context *gin.Context) {
start := time.Now()
fmt.Printf("请求%s进入中间件\n", context.Request.URL)
end := time.Now()
c := end.Sub(start)
fmt.Printf("执行完毕,耗时%v\n", c)
}
}
func main() {
router := gin.Default()
//注册全局中间件
router.Use(MyMiddle())
router.GET("/test", func(context *gin.Context) {
context.String(http.StatusOK, "%s", "success")
})
router.Run(":8080")
}
请求/test进入中间件
执行完毕,耗时996.3µs
Next()会跳过当前中间件后续的逻辑,类似defer,最后再执行c.Next后面的逻辑,也就是说,Next方法前的逻辑是在响应前执行,Next方法后面的逻辑是在响应后执行
局部中间件只在注册的路由和路由组上生效
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"time"
)
func MyMiddle() gin.HandlerFunc {
return func(context *gin.Context) {
start := time.Now()
context.Next()
end := time.Now()
c := end.Sub(start)
fmt.Printf("请求耗时%v\n", c)
}
}
func main() {
router := gin.Default()
// 注册在路由组上
testRouter := router.Group("/test", MyMiddle())
{
testRouter.GET("/t1", func(context *gin.Context) {
context.String(http.StatusOK, "%s", "t1 success")
})
}
// 注册在路由上
router.GET("/index", MyMiddle(), func(context *gin.Context) {
context.String(http.StatusOK, "%s", "success")
})
router.Run(":8080")
}