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.交流群: 2702237 13835667

相關課文
  • GO語言GORM如何更新字段

  • gorm如何創建記錄與模型定義需要注意什麽

  • gorm一般查詢與高級查詢

  • GORM時間戳跟蹤及CURD(增刪改查)

我要說說
網上賓友點評