golang中间件

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

func indexHandler(c *gin.Context) {
    fmt.Println("handle index")
    c.JSON(http.StatusOK, gin.H{"msg": "haha"})
}

// StatCost 计时中间件
func StatCost(c *gin.Context){
    start := time.Now()
    fmt.Println("进入一个中间件m1")
    // 调用后续的处理函数
    c.Next()
    // 阻止调用后续的处理函数
    // c.Abort
    cost := time.Since(start)
    fmt.Printf("请求总共花费时间=%v\n", cost)
    fmt.Println("跳出一个中间件m1")
}

func m2(c *gin.Context) {
    fmt.Println("进入一个中间件m2")
    c.Next()
    fmt.Println("跳出一个中间件m2")
}

func m3(c *gin.Context) {
    fmt.Println("进入一个中间件m3")
    c.Next()
    fmt.Println("跳出一个中间件m3")
}


// 中间件,通常不用上面形式写,而是用闭包
func m4(doCheck bool) gin.HandlerFunc {
    // 这里可以再做一些事情,比如连接数据库,redis等,或其他事情
    fmt.Println("进入中间件之前=================>")
    return func(c *gin.Context) {
        fmt.Println("进入一个中间件m4")
        if doCheck {
            c.Next()
        } else {
            c.Abort()
        }
        fmt.Println("跳出一个中间件m4")
    }
}
//如果在中间件中使用goroutine,应该使用上下文的copy
func m5() gin.HandlerFunc {
    return func(c *gin.Context) {
        fmt.Println("进入一个中间件m5")
        go func(c *gin.Context){
            fmt.Println("在中间件中使用goroutine,应该使用上下文的copy;而不应该直接使用原始的上下文")
        }(c.Copy())
        c.Next()
        fmt.Println("C.Next()之前处理的是请求之前的事情,C.Next()之后是处理的是响应之前的事情")
        fmt.Println("跳出一个中间件m5")
    }
}

func main() {
    router := gin.Default() //默认使用了logger和recover中间件
    // router := gin.New() //不包含任何中间件

    //注册全局中间件
    router.Use(m2, m3, m4(true), m5())

    // 局部中间件
    router.GET("/index", StatCost, indexHandler)

    err := router.Run(":9090")
    if err != nil {
        fmt.Println("启动服务器失败, err:", err)
        return
    }
}

 

posted on 2021-11-14 20:40  myworldworld  阅读(153)  评论(0)    收藏  举报

导航