[go]gin中间件

Go Web轻量级框架Gin学习系列:中间件使用详解

- 中间件的作用:
    请求到达http请求处理方法之前,拦截请求
        认证
        权限校验
        限流
        数据过滤
    处理完请求后,拦截响应,冰进行相应的处理
        统一添加响应头
        数据过滤


- 中间件加的位置
    全局加
    路由组加
    路由明细加
- 默认使用了Logger(), Recovery()全局作用了两个中间件.
r:=gin.Default()

func Default() *Engine {
    debugPrintWARNINGDefault()
    engine := New()
    engine.Use(Logger(), Recovery())
    return engine
}


- gin自带默认有这些中间件
func BasicAuth(accounts Accounts) HandlerFunc
func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc
func Bind(val interface{}) HandlerFunc //拦截请求参数并进行绑定
func ErrorLogger() HandlerFunc       //错误日志处理
func ErrorLoggerT(typ ErrorType) HandlerFunc //自定义类型的错误日志处理
func Logger() HandlerFunc //日志记录
func LoggerWithConfig(conf LoggerConfig) HandlerFunc
func LoggerWithFormatter(f LogFormatter) HandlerFunc
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc
func Recovery() HandlerFunc
func RecoveryWithWriter(out io.Writer) HandlerFunc
func WrapF(f http.HandlerFunc) HandlerFunc //将http.HandlerFunc包装成中间件
func WrapH(h http.Handler) HandlerFunc //将http.Handler包装成中间件
//去除默认全局中间件
r := gin.New()//不带中间件
- 全局中间件
func main() {
    r := gin.Default()

    r.Use(func(c *gin.Context) {
        fmt.Println("hello start")
    })

    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{"name": "m1"})
    })

    r.Run()
}


- 或者
func M1(c *gin.Context) {
    fmt.Println("hello start")
}

func main() {
    r := gin.Default()

    r.Use(M1)

    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{"name": "m1"})
    })

    r.Run()
}
- 路由分组中使用中间件

func main() {
    r := gin.Default()
    v1 := r.Group("/v1", gin.Logger(), gin.Recovery())
    {
        v1.GET("/", func(c *gin.Context) {
            c.JSON(200, gin.H{"name": "m1"})
        })
        v1.GET("/test", func(c *gin.Context) {
            c.JSON(200, gin.H{"name": "m1 test"})
        })
    }
    
    r.Run()
}
- 单个路由使用中间件

func main() {
    r := gin.Default()
    r.GET("/", gin.Recovery(), gin.Logger(), func(c *gin.Context) {
        c.JSON(200, gin.H{"name": "m1"})
    })
    r.Run()
}
- 自定义中间件

//方法1
func MyMiddleware(c *gin.Context) {
    //中间件逻辑
    fmt.Println("hello")
}

func main() {
    r := gin.Default()

    r.Use(MyMiddleware)

    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{"name": "m1"})
    })
    r.Run()
}



//方法2: 返回一个中间件函数

Gin框架自带的中间件方法,都是返回HandlerFunc类型
type HandlerFunc func(*Context)


func MyMiddleware() func(c *gin.Context) {
    //自定义逻辑
    fmt.Println("requesting...") //中间件不打印
    //返回中间件
    return func(c *gin.Context) {  
        //中间件逻辑
        fmt.Println("test2")
    }
}


func main() {
    r := gin.Default()

    r.Use(MyMiddleware()) //加括号

    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{"name": "m1"})
    })
    r.Run()
}
- 值传递

func MyMiddleware(c *gin.Context) {
    c.Set("mykey", 10)
    c.Set("mykey2", "m1")
}
func main() {
    //自定义中间件
    r := gin.New()
    r.GET("", MyMiddleware, func(c *gin.Context) {
        mykey := c.GetInt("mykey") //我们知道设置进行的是整型,所以使用GetInt方法来获取
        mykey2 := c.GetString("mykey2")
        c.JSON(200, gin.H{
            "mykey":  mykey,
            "mykey2": mykey2,
        })
    })
    r.Run()
}


//gin set get取参数
func (c *Context) Set(key string, value interface{})
func (c *Context) Get(key string) (value interface{}, exists bool)

func (c *Context) GetBool(key string) (b bool)
func (c *Context) GetDuration(key string) (d time.Duration)
func (c *Context) GetFloat64(key string) (f64 float64)
func (c *Context) GetInt(key string) (i int)
func (c *Context) GetInt64(key string) (i64 int64)
func (c *Context) GetString(key string) (s string)
func (c *Context) GetStringMap(key string) (sm map[string]interface{})
func (c *Context) GetStringMapString(key string) (sms map[string]string)
func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string)
func (c *Context) GetStringSlice(key string) (ss []string)
func (c *Context) GetTime(key string) (t time.Time)
- 拦截器

func MyMiddleware(c *gin.Context){
    //请求前逻辑
    c.Next()
    //请求后逻辑
}

- gin内置的几个中断用户请求的方法: 返回200,但body里没数据
func (c *Context) Abort()
func (c *Context) AbortWithError(code int, err error) *Error
func (c *Context) AbortWithStatus(code int)

func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{}) //中断请求后,返回json格式的数据

// 示例1:
func MyMiddleware(c *gin.Context) {
    c.Set("key", 1000) //请求前
    c.Next()
    c.JSON(http.StatusOK, c.GetInt("key")) //请求后
}
func main() {
    r := gin.New()
    r.GET("test", MyMiddleware, func(c *gin.Context) {
        k := c.GetInt("key")
        c.Set("key", k+2000)
    })
    r.Run()
}

猜你喜欢

转载自www.cnblogs.com/iiiiiher/p/12202091.html