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会一直执行
相关推荐
有梦想的咸鱼_3 小时前
go实现并发安全hashtable 拉链法
开发语言·golang·哈希算法
杜杜的man7 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*7 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
半桶水专家7 小时前
go语言中package详解
开发语言·golang·xcode
llllinuuu8 小时前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s8 小时前
Golang--协程和管道
开发语言·后端·golang
王大锤43918 小时前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
产幻少年8 小时前
golang函数
golang
为什么这亚子8 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
半桶水专家8 小时前
用go实现创建WebSocket服务器
服务器·websocket·golang