①. 对于分组路由,嵌套使用中间件,可以限定中间件的作用范围.
②. 中间件:
a. 全局中间件
b. 单个路由中间件
c. 群组中间件
(1). Context是Gin的核⼼:
type Context struct {
writermem responseWriter
Request *http.Request
Writer ResponseWriter
Params Params
handlers HandlersChain
index int8
engine *Engine
Keys map[string]interface{}
Errors errorMsgs
Accepted []string
}
// HandlersChain defines a HandlerFunc array.
type HandlersChain []HandlerFunc
// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)
注:
①. 上面可以看出中间件和普通的HandlerFunc没有任何区别.
func MiddleWare() gin.HandlerFunc {
// 返回一个闭包
return func(c *gin.Context) {
t := time.Now()
fmt.Println("before middleware")
// 设置request变量到Context的Key中,通过Get等函数可以取得
c.Set("request", "client_request")
// 发送request之前
c.Next()
// 函数处理之后做一些操作
// 发送requst之后
// 这个c.Write是ResponseWriter,可以获得状态等信息
status := c.Writer.Status()
fmt.Println("after middleware", status)
t2 := time.Since(t)
fmt.Println("time:", t2)
}
}
// 使⽤router装饰中间件
router.Use(MiddleWare())
{
// 后面的路由处理器,可以根据被中间件装饰后提取其值
// ①. 当请求路由时,会执行MiddleWare(),在GET注册的时,同时注册了匿名函数.
router.GET("/middleware", func(c *gin.Context) {
...
})
}
(1). 说明:
①. 只会给c上下文添加一个属性,并赋值.
②. 规则:
a. 注册中间件之前的路由,不会受到中间件影响.
b. 只有注册中间件以下代码的路由函数规则,才会被中间件装饰.
③. 花括号:
a. 使用花括号包含被装饰的路由函数只是一个代码规范.
b. 即使没有被包含在内的路由函数,只要使用router进行路由,都会被装饰.
c. 想要区分权限范围,可以使用组返回的对象注册中间件.
(2). 闭包:
①. 直接使用业务逻辑:
func MiddleWare(c *gin.Context) gin.HandlerFunc {
// 业务逻辑
...
}
router.GET("/home", MiddleWare, func(c *gin.Context) {
...
})
②. 返回一个闭包:
// 好处是能够包含外部作用域变量的引用,可以做一些定制化的操作.
func MiddleWare(debug bool) gin.HandlerFunc {
// 返回一个闭包
return func(c *gin.Context) {
// 业务逻辑
...
if (debug) {
...
}
}
}
router.GET("/home", MiddleWare(true), func(c *gin.Context) {
...
})