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会一直执行
相关推荐
_小许_1 小时前
Go语言实现HTML转PDF
golang·pdf·html
半路程序员6 小时前
Go语言学习(四)
开发语言·学习·golang
秦禹辰7 小时前
轻量级开源文件共享系统PicoShare本地部署并实现公网环境文件共享
开发语言·后端·golang
数据知道11 小时前
Go基础:一文掌握Go语言泛型的使用
开发语言·后端·golang·go语言
QX_hao13 小时前
【Go】--数据类型
开发语言·后端·golang
h79971013 小时前
redis lua脚本(go)调用教程以及debug调试
redis·golang·lua
趣味编程11113 小时前
go的学习2---》并发编程
学习·golang·perl
爱好学习的青年人1 天前
一文详解Go语言字符串
开发语言·后端·golang
思考的笛卡尔1 天前
Go语言实战:高并发服务器设计与实现
服务器·开发语言·golang
会跑的葫芦怪2 天前
Go语言操作Redis
开发语言·redis·golang