gin中间件

字号+ 编辑: Snake 修订: 人在硅谷 来源: 原创 2023-09-10 我要说两句(0)

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

Gin中间件(重要)

Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。

这个钩子函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录校验、日志打印、耗时统计等。

例子:中间件

package main
 
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"time"
)
 

func indexHandler(c *gin.Context){
fmt.Println("index")
name, ok := c.GET("name")
if !ok {
name = "匿名用户"
}
c.JSON(http.StatusOK, gin.H{
"msg": name,
})
}
 

func m1(c *gin.Context){
fmt.Println("m1 in...")

start := time.Now()
c.Next() // 调用后续的处理函数

cost := time.Since(start)
fmt.Printf("cost:%v\n", cost)
fmt.Println("m1 out...")
}
 
func m2(c *gin.Context){
fmt.Println("m2 in...")
c.set("name", "qimi") // m1里做一些操作,m2里拿到

// return // 到这里直接退出,不会打印出m2 out...
fmt.Println("m2 out...")
}
 
func authMiddleware(doCheck bool)gin.HandlerFunc{

// 或这些其他准备工作
return func(c *gin.Context){
if doCheck {

// 是否登录的判断

// c.Next()

// c.Abort()
} else {
c.Next()
}
}
}
 
func main(){
r := gin.Default() // 默认使用Logger()和Recovrey()

r.Use(m1, m2, authMiddleware(true)) // 全局注册中间件函数 m1 m2
 

r.GET("/index", indexHandler)
r.GET("/shop", func(c *gin.Context){
c.JSON(http.StatusOK, gin.H{
"msg": "index",
})
})
r.GET("/user", func(c *gin.Context){
c.JSON(http.StatusOK, gin.H{
"msg":"index ",
})
})
/* (全局已经注册)

xxGroup := r.Group("/xx", authMiddleware(true))
{
xx.Group.GET("/index", func(c *gin.Context){
c.JSON(http.StatusOK, gin.H{"msg": "xxGroup"})
})
}
 

xx2Group := r.Group("/xx2")
xx2Group.Use(authMiddleware(true))
{
xx2Group.Get("/index", func(c *gin.Context){
c.JSON(http.StatusOK, fin.H{"msg": "xx2Group"})
})
}
*/
r.Run() // :8080
}

定义中间件

Gin的中间件必须是一个gin.HandlerFunc类型。例如下面代码一样:定义一个中间件。

// StatCost 是一个统计耗时请求耗时的中间件
func StatCost() gin.HandlerFunc {
return func (c *gin.Context) {
start := time.Now()

c.Set("name", "小王子")

c.Next()

// c.Abort()

cost := time.Since(start)
log.Println(cost)
}
}

注册中间件

在gin框架中,可以为每个路由添加任意数量的中间件。

为全局路由注册

func main(){

// 注册一个全局中间件
r.Use(StatCost())
 
r.Get("/test", func(c *gin.Context){
name := c.MustGet("name").(string) // 从上下文取值
log.Println(name)
c.JSON(http.StatusOK, gin.H{
"message": "Hello world!"
})
})
r.Run()
}

为某个路由单独注册

// 给/test2路由单独注册中间件(可注册多个)
r.GET("/test2", StatCost(), func(c *gin.Context){
name := c.MustGet("name").(string) // 从上下文取值
log.Println(name)
c.JSON(http.StatusOK, gin.H{
"message": "Hello world!",
})
})

为路由组注册中间件

写法1:

shopGroup := r.Group("/shop", StatCost())
{
shopGroup.GET("/index", func(c *gin.Context){...})
...
}

写法2:

shopGroup := r.Group("/shop")
shopGroup.Use(StatCost())
{
shopGroup.GET("/index", func(c *gin.Context){...})
...
}


中间件注意事项

gin默认中间件件

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

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

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

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

gin中间件中使用goroutine

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

例如:

func m1(c *gin.Context){
go funcXX(c.Copy())
}


阅完此文,您的感想如何?
  • 有用

    0

  • 没用

    0

  • 开心

    0

  • 愤怒

    0

  • 可怜

    0

1.如文章侵犯了您的版权,请发邮件通知本站,该文章将在24小时内删除;
2.本站标注原创的文章,转发时烦请注明来源;
3.Q群: 2702237 13835667

相关课文
  • GO语言GORM如何更新字段

  • gorm如何创建记录与模型定义需要注意什么

  • gorm一般查询与高级查询

  • GORM时间戳跟踪及CURD(增删改查)

我要说说
网上嘉宾点评