首页 > 其他分享 >golang gin框架中创建自定义中间件的2种方式总结 - func(*gin.Context)方式和闭包函数方式定义gin中间件

golang gin框架中创建自定义中间件的2种方式总结 - func(*gin.Context)方式和闭包函数方式定义gin中间件

时间:2024-08-15 10:55:24浏览次数:10  
标签:func 方式 函数 中间件 Context gin 定义

在gin框架中,我们可以通过2种方式创建自定义中间件:

1. 直接定义一个类型为 func(*gin.Context)的函数或者方法

        这种方式是我们常用的方式,也就是定义一个参数为*gin.Context的函数或者方法。定义的方法就是创建一个 参数类型为 gin.HandlerFunc 【 他的原型定义为 type HandlerFunc func(*Context) 】的中间件,如: func XxxFoo(c *gin.Context) {}

        注意: 虽然这种方式定义的中间件和入参和路由处理函数的定义是一样的, 但是他们的用途和业务处理方式是有区别的, 在中间件中我们可以通过  c.Next() 方法继续后面的请求, 通过 c.Abort()方法终止后续的请求, 而路由处理函数中我们是不会应用这2个方法的。

示例: 下面定义了一个日志记录的中间件, 我们在这个中间件中还启动了一个协程来处理费时的任务,注意gin框架在中间件中开启协程 是使用的上下文是拷贝的当前上下文


func OperLogMiddleware(c *gin.Context) {
	// 请求操作不做记录
	if c.Request.Method == http.MethodGet {
		c.Next() // 继续后续请求
		return // 退出当前函数
	}

	// 创建在 goroutine 中使用ginx.Context对象的的副本
	cCp := c.Copy()
	go func() {
		// 主这里 在中间件中使用 Context对象的拷贝
		if cCp.Request.Method == "POST" {
			// do something
		}

	}()

    // 如果异常不为空
    if err:=c.Err();err!=nil{
        c.Abort() // 终止后续请求     
    }else{
      // 继续后面的请求
	  c.Next()
    }

}

使用方法:  r.Use(OperLogMiddleware)  // 注意这里只需要指定我们定义的中间件函数名称即可。

func main() {
	r := gin.New()
	r.Use(OperLogMiddleware)

	r.GET("/test", func(c *gin.Context) {
		example := c.MustGet("example").(string)

		// 打印:"12345"
		log.Println(example)
	})

	// 监听并在 0.0.0.0:8080 上启动服务
	r.Run(":8080")
}

2. 闭包函数方式定义中间件,即自定义一个函数并将这个函数的返回类型设置为 func(*gin.Context) 即 gin.HandlerFunc

这种方式的优点在于我们可以在使用中间件的时候给这个中间件传递一些自定义的参数, 如我们在不同模块中使用中间件是可以把模块名称传递进去等。定义方式如下:

// 注意这里的函数入参可以随意定义 返回必须是gin.HandlerFunc
func XxxFoo(x1,x2 string) gin.HandlerFunc {
    // 这里直接返回函数func(c *gin.Context)
    return func(c *gin.Context) {
        // gin 中间件的处理逻辑在这里
    }
}

示例: 我们还是上面的示例,改写为闭包函数方式来定义中间件。


// 闭包函数方式定义中间件
// 注意这里的这个闭包函数的入参可以随意,你要怎么定义都可以,但是返回必须是gin.HandlerFunc类型,即func(c *gin.Context)类型
func OperLogClosure(moduleName string) gin.HandlerFunc {

	// 定义处理函数 gin.HandlerFunc
	var handlerFn = func(c *gin.Context) {

		// 请求操作不做记录
		if c.Request.Method == http.MethodGet {
			c.Next() // 继续后续请求
			return   // 退出当前函数
		}

		// 创建在 goroutine 中使用ginx.Context对象的的副本
		cCp := c.Copy()
		go func() {
			// 主这里 在中间件中使用 Context对象的拷贝
			if cCp.Request.Method == "POST" {
				// do something
			}

		}()

		// 如果异常不为空
		if err := c.Err(); err != nil {
			c.Abort() // 终止后续请求
		} else {
			// 继续后面的请求
			c.Next()
		}
	}
	// 返回这个函数 , 当然我们也可以直接 return 这个函数的定义
	return handlerFn
}

使用方法:  r.Use(OperLogClosure("system"))  // 注意这里在Use的时候是直接执行我们定义的闭包函数

func main() {
	r := gin.New()
    // 注意这里Use的参数 我们在这里直接执行我们定义的闭包函数
	r.Use(OperLogClosure("system"))

	r.GET("/test", func(c *gin.Context) {
		example := c.MustGet("example").(string)

		// 打印:"12345"
		log.Println(example)
	})

	// 监听并在 0.0.0.0:8080 上启动服务
	r.Run(":8080")
}

总结:gin框架中的中间件实际上也就是一个类型为 func(c *gin.Context) 的函数或者方法定义即可, 我们可以采用直接定义函数的方式或者采用闭包方式来定义中间件,相比之下,闭包方式拥有更好的灵活性,可以随意给我们的中间件传递初始参数, 而普通方式定义的中间件要传递参数就只能是使用全局的上下文了。 同时我们还需要知道gin框架的中间件中的Abort方法和Next方法的使用,以及如何中断当前请求后继续后续请求等。

标签:func,方式,函数,中间件,Context,gin,定义
From: https://blog.csdn.net/tekin_cn/article/details/141183607

相关文章

  • PHP转Go系列 | ThinkPHP与Gin框架之打造基于WebSocket技术的消息推送中心
    大家好,我是码农先森。在早些年前客户端想要实时获取到最新消息,都是使用定时长轮询的方式,不断的从服务器上获取数据,这种粗暴的骚操作实属不雅。不过现如今我也还见有人还在一些场景下使用,比如在PC端扫描二维码,然后使用长轮询的方式从服务端获取最新的扫码信息,来判断用户是否已经......
  • nginx的功能?部署前端代码的步骤?负载均衡的功能,说一下。
    nginx的功能?部署前端代码的步骤?负载均衡的功能,说一下。使用Nginx部署前端项目的详细步骤作者:rousong2024.01.2920:50浏览量:423使用Nginx部署前端项目的详细步骤(baidu.com)简介:本文将介绍使用Nginx部署前端项目的详细步骤,包括下载和安装Nginx、配置Nginx、部署前端项目等。......
  • java调用python代码的两种方式:Runtime.exec()和Jython
    要在Java中调用Python代码,你可以使用几种不同的方法。这里我将介绍两种常见的方法:使用Runtime.exec()和使用第三方库如Jython。1.使用Runtime.exec()这种方法涉及到通过系统命令的方式执行Python脚本。下面是一个简单的示例,展示如何使用Runtime.exec()在Jav......
  • 腾讯微服务框架(TSF)-令牌桶限流的实现方式
    1为什么需要限流限流,也称流量控制。是指系统在面临高并发,或者大流量请求的情况下,限制新的请求对系统的访问,从而保证系统的稳定性。限流会导致部分用户请求处理不及时或者被拒,这就影响了用户体验。所以一般需要在系统稳定和用户体验之间平衡一下。举个生活的例子:比如我们的交......
  • docker-compose部署tdengine 3.3.0.0集群
    说明:官方文档提供dockerswarm部署多台服务器集群方式,不适用于公司目前部署方式,故研究多台服务器docker部署集群目前只是部署,还未生产使用,仅供参考一、环境:服务器3台,系统为Ubuntu20.04.4LTSemscluster0110.1.1.103emscluster0210.1.1.104emscluster0310.1.1.105......
  • Nginx Proxy Manager反向代理工具
    简介NginxProxyManager(以下简称NPM)就是一个Nginx的代理管理器,它最大的特点是简单方便。即使是没有Nginx基础的小伙伴,也能轻松地用它来完成反向代理的操作,不需要自己写复杂的nginx配置,而且因为自带面板,操作极其简单。NginxProxyManager后台还可以一键申请SSL证书,并......
  • 【Nginx】nginx案例-配置文件
      案例一、【web服务应用】七层反向代理,负载均衡,动静分离 vim/usr/local/nginx/conf/nginx.conf......http{......#gzipon;#配置负载均衡的服务器列表,weight参数表示权重,权重越高,被分配到的概率越大upstreamtomcat_server{server1......
  • 周期补数据、定时补数据,深入了解两种补数据的特殊方式
    在当今数字化的时代,数据已然成为企业决策与运营的关键要素。而保障数据的完整性、准确性以及及时性,对于企业的发展有着举足轻重的意义。在数据运维管理范畴内,补数据属于大数据开发和运维人员常用的运维操作手段。周期补数据和定时补数据作为两个相对特殊的补数据方式,在各类不同的......
  • nginx 配置
    Nginxvue项目配置好后,刷新页面会出现404?方案:增加重定向try_files$uri$uri//index.html;mac配置Nginx1、brewinstallnginx安装nginx2、brewinfonginx查询nginx信息 3、查看/修改nginx的配置文件:打开文件/opt/homebrew/etc/nginx/,可以看到有nginx.conf文件,在该......
  • 高级工程师面试大全- 消息中间件篇
    1.rabbitMQ1.1使用RabbitMQ有什么好处?1、解耦,系统A在代码中直接调用系统B和系统C的代码,如果将来D系统接入,系统A还需要修改代码,过于麻烦!2、异步,将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度3、削峰,并发量大的时候,所有的请求直接怼到数据库,造成数据库连......