本文已参与「新人创作礼」活动,一起开启掘金创作之路。
全局中间件
全局中间件使用 r.Use()配置 部分代码:
func initMiddleware(ctx *gin.Context) {
fmt.Println("全局中间件 通过 r.Use 配置")
// 调用该请求的剩余处理程序
ctx.Next()
}
main.go:
func main() {
r := gin.Default()
r.Use(initMiddleware) //定义全局中间件,在配置路由之上
r.GET("/", func(ctx *gin.Context) {
ctx.String(200, "xxxxxxx")
})
r.GET("/index", func(ctx *gin.Context) {
ctx.String(200, "xxxxxxx")
})
r.Run(":8080")
}
在路由分组中配置中间件
1、路由分组一共有两种写法 方法一:在r.Group中的设置中间件。
shopGroup := r.Group("/shop", initmirr()) //initmirr()为中间件
{
shopGroup.GET("/index", func(c *gin.Context) {...})
}
方法二:
shopGroup := r.Group("/shop")
//在 r.Group()下面使用全局中间件
shopGroup.Use(StatCost()) {
shopGroup.GET("/index", func(c *gin.Context) {
...
})
...
}
中间件和对应控制器之间共享数据
1、设置值
ctx.Set(key,vlaue)
如:
ctx.Set("username", "小明")
2、获取值
username, _ := ctx.Get("username")
3、中间件设置值
func InitAdminMiddleware(ctx *gin.Context) {
fmt.Println("路由分组中间件")
// 可以通过 ctx.Set 在请求上下文中设置值,后续的处理函数能够取到该值
ctx.Set("username", "小明")
// 调用该请求的剩余处理程序
ctx.Next() }
4、控制器获取值
func (c UserController) Index(ctx *gin.Context) {
//获取值
username, _ := ctx.Get("username")
fmt.Println(username)
ctx.String(http.StatusOK, "首页")
}
注意事项
1、 gin.Default() 默认使用了 Logger 和 Recovery 中间件,其中:
<1>• Logger 中间件将日志写入 gin.DefaultWriter,即使配置了GIN_MODE=release。
<2>• Recovery 中间件会 recover 任何 panic。如果有 panic 的话,会写入500 响应码。
如果不想使用上面两个默认的中间件,可以使用 gin.New() 新建一个没有任何默认中间件的路由。
2、gin 中间件中使用 goroutine
当在中间件或 handler 中启动新的 goroutine 时,不能使用原始的上下文(c *gin.Context),必须使用其只读副本(c.Copy())
r.GET("/", func(c *gin.Context) {
cCp := c.Copy()
go func() {
// 延时5秒
time.Sleep(5 * time.Second)
// 这里使用你创建的副本
fmt.Println("Done! in path " + cCp.Request.URL.Path)
}()
c.String(200, "首页")
})