• gin 中间件


    中间件格式

    gin.HandlerFunc,满足这个函数即可

    //gin.HandlerFunc
    type HandlerFunc func(*Context)
    
    • 1
    • 2

    使用

    通过 engine.Use(gin.HandlerFunc) 注册

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    	"time"
    )
    
    func log() gin.HandlerFunc {
    	return func(c *gin.Context) {
    		now := time.Now()
           //执行下一个中间件 
    		c.Next()
    		end := time.Since(now)
    		fmt.Printf("请求耗时 %s", end)
    	}
    }
    
    func main() {
    	r := gin.New()
    	r.Use(log())
    	r.GET("/ping", func(c *gin.Context) {
    		c.JSON(http.StatusOK, gin.H{
    			"message": "pong",
    		})
    	})
    	r.Run(":8080")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    终止中间件

    一般中间件的实现有两种模式:
    1.基于责任链的中间件,在中间件中return就不会执行下一个中间件
    2.基于AOP切面的中间件,return 不一定就不会执行下一个中间件

    gin的中间件就是基于AOP打造的。其中return还是会执行下一个中间件的,如果不想执行,需要调用gin.Context.Abort()方法

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    	"time"
    )
    
    func log() gin.HandlerFunc {
    	return func(c *gin.Context) {
    		now := time.Now()
    		//想要终止中间件的执行,return 是无效的
    		c.Abort()
    		end := time.Since(now)
    		fmt.Printf("请求耗时 %s", end)
    	}
    }
    
    func main() {
    	r := gin.New()
    	r.Use(log())
    	r.GET("/ping", func(c *gin.Context) {
    		c.JSON(http.StatusOK, gin.H{
    			"message": "pong",
    		})
    	})
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    return 不能终止的原因

    //查看Next()方法源码
    func (c *Context) Next() {
    	c.index++
    	for c.index < int8(len(c.handlers)) {
    		c.handlers[c.index](c)
    		c.index++
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    c.handlers 中是中间件的执行函数,c.index 决定应该执行那个中间件了。
    假设现在c.haandlers中有A,B,C,D四个中间件。最开始gin会调用Next(),
    执行顺序A,B,C,D。其中A终止了并不会阻碍B,C,D的执行。如果中间件中不使用
    Next(),这时候他们是平行的。当A中调用了Next(),A中就嵌套了B,C,D中间件的执行。Abort() 将c.index 调整到一个远远大于len(c.handlers)的值,来阻止后续中间件的执行。

  • 相关阅读:
    L1-015 跟奥巴马一起画方块
    用视频给珠峰建了个三维模型
    Mysql JDBC 编程
    [附源码]SSM计算机毕业设计学生实习管理系统JAVA
    Linux-----网络套接字编程
    开发小程序插件如何实现盈利?
    工业视觉——打光
    java后端操作树结构
    网络安全(黑客)自学笔记
    LabVIEW下载 安装 和谐 与卸载教程
  • 原文地址:https://blog.csdn.net/qq_29744347/article/details/125994941