gin中间件&控制器

中间件

Gin 框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。这个钩子函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等。

通俗的讲:中间件就是匹配路由前和匹配路由完成后执行的一系列操作

路由中间件

Gin 中的中间件必须是一个 gin.HandlerFunc 类型,配置路由的时候可以传递多个 func 回调函数,最后一个 func 回调函数前面触发的方法都可以称为中间件

go 复制代码
// 请求方式的源码参数,... 可以传入多个func(context *gin.Context)
// 可以在func(context *gin.Context)之前传入自定义的一些处理方法
(relativePath string, handlers ...HandlerFunc)
定义和使用路由中间件
写法一
go 复制代码
// 定义一个中间件要执行的方法
func MiddlewareFunc() {
	fmt.Println("中间件方法")

}

func ApiRoutersInit(router *gin.Engine) {

	apiRouter := router.Group("api")
	{
		apiRouter.GET("list",
			func(context *gin.Context) {
				// 请求前执行中间件方法
				MiddlewareFunc()
			},
			// 执行请求
			func(context *gin.Context) {
				context.String(http.StatusOK, "ok")

			})

	}
}
写法二
go 复制代码
// 定义一个中间件要执行的方法
func MiddlewareFunc(context *gin.Context) {
	fmt.Println("中间件方法")

}

func ApiRoutersInit(router *gin.Engine) {

	apiRouter := router.Group("api")
	{	
		// 写法二
		apiRouter.GET("list", MiddlewareFunc,func(context *gin.Context) {
				context.String(http.StatusOK, "ok")

			})

	}
}
ctx.Next()

中间件里面加上 ctx.Next()可以让我们在路由匹配完成后执行一些操作

go 复制代码
func MiddlewareFunc(context *gin.Context) {
	
	fmt.Println("请求执行前")
  // 调用该请求的剩余处理程序
	context.Next() 
  // 执行后面的func(context *gin.Context)方法
  // 每调用一次	context.Next() ,向后执行一个func(context *gin.Context)
  
  // 执行完之后再执行打印
	fmt.Println("请求执行完成")


}
ctx.Abort

Abort 是终止的意思, ctx.Abort() 表示终止调用该请求的剩余处理程序

go 复制代码
func MiddlewareFunc(context *gin.Context) {
	fmt.Println("aaa")
	// 终止该请求的剩余处理程序 
	context.Abort()
	fmt.Println("这里继续打印")
  
  


}

全局中间件

go 复制代码
func main() {
	router := gin.Default()

	// 在匹配路由之前配置全局中间件

	// 使用Use配置全局中间件,参数就是中间件方法,可以传入多个,
	router.Use(MiddlewareFunc1,MiddlewareFunc2)

	router.GET("/", func(context *gin.Context) {
		context.String(http.StatusOK, "ok")

	})

	// 将默认引擎传给其他文件定义的接收引擎的方法
	api.ApiRoutersInit(router)
	router.Run()

}

路由分组中间件

方法一
go 复制代码
func ApiRoutersInit(router *gin.Engine) {
	// 在路由分组的Group后配置中间件
	apiRouter := router.Group("api",MiddlewareFunc)
	{
		apiRouter.GET("list",
			// 执行请求
			func(context *gin.Context) {
				context.String(http.StatusOK, "ok")

			})

	}
}
方法二
go 复制代码
func ApiRoutersInit(router *gin.Engine) {
	apiRouter := router.Group("api")
	// 调用group对象 配置中间件
	apiRouter.Use(MiddlewareFunc)
	{
		apiRouter.GET("list",
			// 执行请求
			func(context *gin.Context) {
				context.String(http.StatusOK, "ok")

			})

	}
}

中间件和对应控制器共享数据

go 复制代码
// 中间件

func MiddlewareFunc(context *gin.Context) {
	// 通过Set设置一个数据 k,v
	context.Set("name", "li")

}
go 复制代码
// 控制器
func (a ApiController) ApiSetInfo(context *gin.Context) {
  // 通过.Get(key) 获取值,获取到的是一个any类型的值和是否异常的bool
	username, _ := context.Get("name")
	// 通过类型断言获取string类型的name
	name, _ := username.(string)
	context.String(http.StatusOK, name)
}

中间件注意事项

gin默认中间件

gin.Default()默认使用了 Logger 和 Recovery 中间件,其中:

• Logger 中间件将日志写入 gin.DefaultWriter,即使配置了 GIN_MODE=release。

• Recovery 中间件会 recover 任何 panic。如果有 panic 的话,会写入 500 响应码。

如果不想使用上面两个默认的中间件,可以使用 gin.New()新建一个没有任何默认中间件的路由

中间件中使用协程

当在中间件或 handler 中启动新的 goroutine 时,不能使用原始的上下文(c *gin.Context),必须使用其只读副本(c.Copy())

go 复制代码
func MiddlewareFunc(context *gin.Context) {
	c := context.Copy()

	go func() {
		fmt.Println("url是", c.Request.URL)
	}()

	go func() {
		fmt.Println("body是", c.Request.Body)
	}()

}
	// 不需要wait等待协程完成,因为主程序main.go会一直执行
相关推荐
高hongyuan1 小时前
Go语言教程-占位符及演示代码
开发语言·后端·golang
风无雨5 小时前
GO启动一个视频下载接口 前端可以边下边放
前端·golang·音视频
LuckyLay1 天前
使用 Docker 搭建 Go Web 应用开发环境——AI教你学Docker
前端·docker·golang
{⌐■_■}1 天前
【软件工程】tob和toc含义理解
前端·数据库·mysql·golang·软件工程·tidb
hackchen2 天前
Go与JS无缝协作:Goja引擎实战之错误处理最佳实践
开发语言·javascript·golang
争不过朝夕,又念着往昔2 天前
Go语言反射机制详解
开发语言·后端·golang
Jerry Lau2 天前
go go go 出发咯 - go web开发入门系列(二) Gin 框架实战指南
前端·golang·gin
Code季风2 天前
微服务分布式配置中心:Gin Web 服务层与 gRPC 服务层集成 Nacos 实战
分布式·微服务·rpc·架构·go·gin·consul
witton2 天前
Go语言网络游戏服务器模块化编程
服务器·开发语言·游戏·golang·origin·模块化·耦合
叹一曲当时只道是寻常2 天前
Softhub软件下载站实战开发(十六):仪表盘前端设计与实现
前端·golang