您的位置:首页 > 游戏 > 手游 > 2022热点新闻事件_大冶seo网站优化排名推荐_短视频代运营费用明细_短视频推广引流方案

2022热点新闻事件_大冶seo网站优化排名推荐_短视频代运营费用明细_短视频推广引流方案

2025/4/11 11:23:08 来源:https://blog.csdn.net/qq_73092699/article/details/146436432  浏览:    关键词:2022热点新闻事件_大冶seo网站优化排名推荐_短视频代运营费用明细_短视频推广引流方案
2022热点新闻事件_大冶seo网站优化排名推荐_短视频代运营费用明细_短视频推广引流方案

Gin 框架的中间件

Gin 中间件是一种用于处理 HTTP 请求的钩子函数,可以在请求到达业务逻辑处理函数(如路由处理函数)之前或之后执行特定操作。其核心目标是解耦通用功能(如日志、认证、跨域处理)与业务逻辑,提升代码复用性和可维护性。

一、中间件的核心机制

洋葱模型(Onion Model)

Gin 中间件的执行流程类似 “洋葱” 分层结构:请求按中间件注册顺序进入,执行 c.Next() 后跳转到下一中间件或业务逻辑,返回时再以相反顺序执行剩余代码。例如:

请求 → 中间件1 → 中间件2 → 业务逻辑 → 中间件2 → 中间件1 → 响应

这种机制允许在请求前后执行逻辑(如统计耗时、记录日志)

上下文(gin.Context)

中间件通过 gin.Context 共享数据和控制流程:

  • 数据传递:使用 c.Set("key", value) 存储数据,c.Get("key") 获取数据(如传递请求 ID)。
  • 流程控制c.Next() 继续执行后续中间件,c.Abort() 终止请求并直接返回响应(如认证失败时)

二、中间件的分类与使用

1. 全局中间件

作用于所有请求,通过 r.Use() 注册。例如:

r := gin.Default()
r.Use(gin.Logger())  // 内置日志中间件
r.Use(AuthMiddleware) // 自定义认证中间件

常用于日志记录、全局异常捕获等场景。

2. 路由组中间件

仅作用于特定路由组,通过 group.Use() 注册。例如:

admin := r.Group("/admin")
admin.Use(AuthMiddleware) // 仅对 /admin 路径生效
admin.GET("/dashboard", DashboardHandler)

适用于权限分层(如后台管理接口需认证)。

3. 局部中间件

仅作用于单个路由,直接在路由定义中指定。例如:

r.GET("/profile", AuthMiddleware, ProfileHandler)

适用于特定接口需要额外校验的场景(如敏感数据接口)。

三、中间件的使用示例

单独注册中间件
import ("fmt""github.com/gin-gonic/gin""net/http"
)
func indexHandler(c *gin.Context) {fmt.Println("index.....")c.JSON(http.StatusOK, gin.H{"msg": "index",})
}//定义一个中间件
func m1(c *gin.Context) {fmt.Println("m1 in.........")
}
func main() {r := gin.Default()//m1处于indexHandler函数的前面,请求来之后,先走m1,再走indexr.GET("/index", m1, indexHandler)_ = r.Run()
}

浏览器访问localhost:8080/index

控制台输出

m1 in…
index…

多个中间件

router.GET 后面可以跟很多 HandlerFunc 方法,这些方法其实都可以叫中间件

package mainimport ("fmt""github.com/gin-gonic/gin"
)func m1(c *gin.Context) {fmt.Println("m1 ...in")
}
func m2(c *gin.Context) {fmt.Println("m2 ...in")
}func main() {router := gin.Default()router.GET("/", m1, func(c *gin.Context) {fmt.Println("index ...")c.JSON(200, gin.H{"msg": "响应数据"})}, m2)router.Run(":8080")
}// m1 ...in
// index ...
// m2 ...in
中间件拦截响应

c.Abort(): 调用该函数会立即终止当前中间件函数的执行,并且不会再调用后续的中间件函数或路由处理函数

package mainimport ("fmt""github.com/gin-gonic/gin"
)func m1(c *gin.Context) {fmt.Println("m1 ...in")c.JSON(200, gin.H{"msg": "第一个中间件拦截了"})c.Abort()
}
func m2(c *gin.Context) {fmt.Println("m2 ...in")
}func main() {router := gin.Default()router.GET("/", m1, func(c *gin.Context) {fmt.Println("index ...")c.JSON(200, gin.H{"msg": "响应数据"})}, m2)router.Run(":8080")
}// m1 ...in
中间件放行

c.Next(): 调用该函数会将控制权交给下一个中间件函数,如果没有下一个中间件函数,则将控制权交给处理请求的路由处理函数

package mainimport ("fmt""github.com/gin-gonic/gin"
)func m1(c *gin.Context) {fmt.Println("m1 ...in")c.Next()fmt.Println("m1 ...out")
}
func m2(c *gin.Context) {fmt.Println("m2 ...in")c.Next()fmt.Println("m2 ...out")
}func main() {router := gin.Default()router.GET("/", m1, func(c *gin.Context) {fmt.Println("index ...in")c.JSON(200, gin.H{"msg": "响应数据"})c.Next()fmt.Println("index ...out")}, m2)router.Run()
}// m1 ...in
// index ...in
// m2 ...in
// m2 ...out
// index ...out
// m1 ...out
全局注册中间件

使用 Use 去注册全局中间件,Use 接收的参数也是多个 HandlerFunc

package mainimport ("fmt""github.com/gin-gonic/gin"
)func m10(c *gin.Context) {fmt.Println("m1 ...in")c.Next()fmt.Println("m1 ...out")
}func main() {router := gin.Default()router.Use(m10)router.GET("/", func(c *gin.Context) {fmt.Println("index ...in")c.JSON(200, gin.H{"msg": "index"})c.Next()fmt.Println("index ...out")})router.Run()}// m1 ...in
// index ...in
// index ...out
// m1 ...out

路由

路由分组

将一系列的路由放到一个组下,统一管理。例如,以下的路由前面统一加上 api 的前缀

package mainimport "github.com/gin-gonic/gin"func main() {router := gin.Default()r := router.Group("/api")r.GET("/index", func(c *gin.Context) {c.String(200, "index")})r.GET("/home", func(c *gin.Context) {c.String(200, "home")})router.Run()
}

路由分组注册中间件

package mainimport ("fmt""github.com/gin-gonic/gin"
)func middle(c *gin.Context) {fmt.Println("middle ...in")
}func main() {router := gin.Default()r := router.Group("/api").Use(middle)  // 可以链式,也可以直接r.Use(middle)r.GET("/index", func(c *gin.Context) {c.String(200, "index")})r.GET("/home", func(c *gin.Context) {c.String(200, "home")})router.Run()
}

这样写我们就可以指定哪一些分组下可以使用中间件了

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com