Gin 中间件

在Gin框架中,中间件(Middleware)是处理HTTP请求的重要组成部分,允许开发者在请求到达处理函数前后执行特定逻辑。以下是对Gin中间件的详细解释:
1. 中间件的基本概念
中间件是一种函数(类型为gin.HandlerFunc
),接收*gin.Context
参数,用于:
- 拦截请求:在请求处理前或处理后执行代码。
- 共享逻辑:复用如日志、认证、错误处理等逻辑。
- 控制流程:决定是否继续执行后续中间件或终止请求。
2. 中间件的执行流程
Gin中间件遵循洋葱模型,按添加顺序依次执行,流程如下:
- 顺序执行:先添加的中间件先执行。
c.Next()
:调用后,暂停当前中间件,执行后续中间件及路由处理函数。- 逆序返回:后续处理完成后,回到当前中间件继续执行剩余代码。
示例:
1func Middleware1(c *gin.Context) {
2 fmt.Println("Start Middleware1")
3 c.Next() // 执行后续中间件
4 fmt.Println("End Middleware1")
5}
6
7func Middleware2(c *gin.Context) {
8 fmt.Println("Start Middleware2")
9 c.Next()
10 fmt.Println("End Middleware2")
11}
12
13// 添加顺序:Middleware1 → Middleware2
14// 输出顺序:
15// Start Middleware1 → Start Middleware2 → 处理请求 → End Middleware2 → End Middleware1
3. 中间件的使用方式
全局中间件
通过gin.Engine.Use()
添加,对所有路由生效:
1r := gin.Default()
2r.Use(Middleware1, Middleware2)
路由组中间件
对特定路由组生效:
1adminGroup := r.Group("/admin")
2adminGroup.Use(AuthMiddleware()) // 仅/admin路径生效
路由级别中间件
在定义路由时添加:
1r.GET("/user", AuthMiddleware(), UserHandler)
4. 常用中间件场景
日志记录
1func Logger() gin.HandlerFunc {
2 return func(c *gin.Context) {
3 start := time.Now()
4 c.Next()
5 duration := time.Since(start)
6 log.Printf("路径: %s | 耗时: %v", c.Request.URL, duration)
7 }
8}
身份验证
1func AuthMiddleware() gin.HandlerFunc {
2 return func(c *gin.Context) {
3 token := c.GetHeader("Authorization")
4 if token != "valid_token" {
5 c.AbortWithStatusJSON(401, gin.H{"error": "未授权"})
6 return
7 }
8 c.Next()
9 }
10}
错误处理
1func RecoveryMiddleware() gin.HandlerFunc {
2 return func(c *gin.Context) {
3 defer func() {
4 if err := recover(); err != nil {
5 c.AbortWithStatusJSON(500, gin.H{"error": "服务器内部错误"})
6 }
7 }()
8 c.Next()
9 }
10}
跨域处理(CORS)
1func CorsMiddleware() gin.HandlerFunc {
2 return func(c *gin.Context) {
3 c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
4 c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
5 c.Next()
6 }
7}
5. 关键方法
c.Next()
:执行后续中间件和路由处理函数。c.Abort()
:终止后续处理,当前中间件后的逻辑不再执行。c.AbortWithStatus(code)
:终止并返回HTTP状态码。c.Set(key, value)
/c.Get(key)
:在中间件间传递数据。
6. 内置中间件
Gin默认提供两个中间件:
gin.Logger()
:记录请求日志。gin.Recovery()
:捕获panic并返回500错误。
通过gin.Default()
自动加载,而gin.New()
则不会。
7. 自定义中间件示例
记录响应时间:
1func ResponseTime() gin.HandlerFunc {
2 return func(c *gin.Context) {
3 start := time.Now()
4 c.Next()
5 c.Writer.Header().Set("X-Response-Time", fmt.Sprintf("%v", time.Since(start)))
6 }
7}
使用中间件:
1r := gin.New()
2r.Use(ResponseTime())
8. 注意事项
- 执行顺序:中间件按添加顺序执行,需注意依赖关系。
- 性能:避免在中间件中执行阻塞操作(如同步数据库查询)。
- 上下文安全:
*gin.Context
是协程安全的,可传递请求级别数据。
通过合理使用中间件,可以极大提升Gin应用的灵活性和可维护性,实现功能解耦和逻辑复用。