国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Go學(xué)習(xí)第十七章——Gin中間件與路由

這篇具有很好參考價(jià)值的文章主要介紹了Go學(xué)習(xí)第十七章——Gin中間件與路由。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1 單獨(dú)注冊中間件

Gin框架允許開發(fā)者在處理請求的過程中,加入用戶自己的鉤子(Hook)函數(shù)。這個鉤子函數(shù)就叫中間件,中間件適合處理一些公共的業(yè)務(wù)邏輯,比如登錄認(rèn)證、權(quán)限校驗(yàn)、數(shù)據(jù)分頁、記錄日志、耗時(shí)統(tǒng)計(jì)等
即比如,如果訪問一個網(wǎng)頁的話,不管訪問什么路徑都需要進(jìn)行登錄,此時(shí)就需要為所有路徑的處理函數(shù)進(jìn)行統(tǒng)一一個中間件

Gin中的中間件必須是一個gin.HandlerFunc類型

1.1 入門案例

我們先看一下Get函數(shù)能夠接收的參數(shù):

func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodGet, relativePath, handlers)
}

type HandlerFunc func(*Context)

從這個函數(shù)里,我們能看到它可以,它可以接收很多的HandlerFunc類型的數(shù)據(jù),并且發(fā)現(xiàn)是func(*Context)數(shù)據(jù)類型都可以,所以,我們可以定義很多個中間件,它必須是*gin.Context類型

  1. 定義一個中間件
func m1(c *gin.Context) {
    fmt.Println("m1 in.........")
}
  1. 寫一個函數(shù),在前端響應(yīng)的數(shù)據(jù),作為參考
func indexHandler(c *gin.Context) {
    fmt.Println("index.....")
    c.JSON(http.StatusOK, gin.H{
       "msg": "index",
    })
}
  1. 完整代碼
func indexHandler(c *gin.Context) {
    fmt.Println("index.....")
    c.JSON(http.StatusOK, gin.H{
       "msg": "index",
    })
}

// 定義一個中間件
func m1(c *gin.Context) {
    fmt.Println("m1 in.........")
}

func main() {
    r := gin.Default()
    //m1處于indexHandler函數(shù)的前面,請求來之后,先走m1,再走index
    r.GET("/index", m1, indexHandler)

    r.Run(":8000")
}

注意:m1處于indexHandler函數(shù)的前面,請求來之后,先走m1,再走index

然后,使用游覽器訪問對應(yīng)的請求,看一下輸出:

Go學(xué)習(xí)第十七章——Gin中間件與路由,golang,學(xué)習(xí),gin,開發(fā)語言,筆記,后端

驗(yàn)證完畢??!~

1.2 多個中間件

router.GET,后面可以跟很多HandlerFunc方法,這些方法其實(shí)都可以叫中間件

package main

import (
  "fmt"
  "github.com/gin-gonic/gin"
)

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

func main() {
  router := gin.Default()

  router.GET("/", m1, func(c *gin.Context) {
    fmt.Println("index ...")
    c.JSON(200, gin.H{"msg": "響應(yīng)數(shù)據(jù)"})
  }, m2)

  router.Run(":8080")
}

這里就不演示了~~

1.3 中間件攔截響應(yīng)

c.Abort()函數(shù),作用:攔截,后續(xù)的HandlerFunc就不會執(zhí)行了

package main

import (
  "fmt"
  "github.com/gin-gonic/gin"
)

func m1(c *gin.Context) {
  fmt.Println("m1 ...in")
  c.JSON(200, gin.H{"msg": "第一個中間件攔截了"})
  c.Abort()
}
func m2(c *gin.Context) {
  fmt.Println("m2 ...in")
}

func main() {
  router := gin.Default()

  router.GET("/", m1, func(c *gin.Context) {
    fmt.Println("index ...")
    c.JSON(200, gin.H{"msg": "響應(yīng)數(shù)據(jù)"})
  }, m2)

  router.Run(":8080")
}

運(yùn)行后,去游覽器試一下,會發(fā)現(xiàn)只輸出:m1 …in,也就是被第一個攔截器攔截了~

1.4 中間件放行

c.Next()函數(shù),作用:Next前后形成了其他語言中的請求中間件和響應(yīng)中間件

package main

import (
  "fmt"
  "github.com/gin-gonic/gin"
)

func m1(c *gin.Context) {
  fmt.Println("m1 ...in")
  c.Next()
  fmt.Println("m1 ...out")
}
func m2(c *gin.Context) {
  fmt.Println("m2 ...in")
  c.Next()
  fmt.Println("m2 ...out")
}

func main() {
  router := gin.Default()

  router.GET("/", m1, func(c *gin.Context) {
    fmt.Println("index ...in")
    c.JSON(200, gin.H{"msg": "響應(yīng)數(shù)據(jù)"})
    c.Next()
    fmt.Println("index ...out")
  }, m2)

  router.Run(":8080")
}

輸出結(jié)果:

m1 ...in
index ...in 
m2 ...in    
m2 ...out   
index ...out
m1 ...out   

輸出的方式,有點(diǎn)像棧,先進(jìn)去的m1...out最后再輸出~

2 全局注冊中間件

在Gin框架中,可以使用Use方法注冊全局中間件。全局中間件會對所有的請求都生效。

func main() {
    r := gin.Default()

    r.Use(Logger()) // 注冊全局中間件

    r.GET("/hello", HelloHandler)

    r.Run(":8080")
}

// Logger 是一個全局中間件
func Logger() gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now()

        c.Next()

        end := time.Now()
        latency := end.Sub(start)

        log.Printf("[%s] %s %s %v", c.Request.Method, c.Request.URL.Path, c.Request.RemoteAddr, latency)
    }
}

func HelloHandler(c *gin.Context) {
    c.String(http.StatusOK, "Hello, Gin!")
}

在上面的示例中,Logger函數(shù)是一個全局中間件。它在處理請求之前記錄了請求的相關(guān)信息,并在請求處理完成后打印了請求的耗時(shí)。

3 自定義參數(shù)傳遞

在中間件之間傳遞自定義參數(shù)是一種常見的需求。在Gin框架中,可以使用Context.SetContext.Get方法來傳遞自定義參數(shù),并且傳遞的數(shù)據(jù)是一個key-value

func main() {
    r := gin.Default()

    r.Use(AddCustomData("custom data"))

    r.GET("/hello", HelloHandler)

    r.Run(":8080")
}

func AddCustomData(data string) gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Set("customData", data) // 設(shè)置自定義參數(shù)

        c.Next()
    }
}

func HelloHandler(c *gin.Context) {
    customData, exists := c.Get("customData") // 獲取自定義參數(shù)

    if exists {
        c.String(http.StatusOK, "Hello, Gin! Custom data: %s", customData)
    } else {
        c.String(http.StatusOK, "Hello, Gin!")
    }
}

在上面的示例中,AddCustomData函數(shù)返回了一個中間件函數(shù),用于在Context中設(shè)置自定義參數(shù)。在HelloHandler處理函數(shù)中,通過Context.Get方法獲取自定義參數(shù)并使用。

4 路由分組

4.1 入門案例

將一系列的路由放到一個組下,統(tǒng)一管理。例如,以下的路由前面統(tǒng)一加上api的前綴

package main

import "github.com/gin-gonic/gin"

func main() {
  router := gin.Default()

  r := router.Group("/api")
  r.GET("/index", func(c *gin.Context) {
    c.String(200, "index")
  })
  r.GET("/home", func(c *gin.Context) {
    c.String(200, "home")
  })

  router.Run(":8080")
}

4.2 路由分組注冊中間件

package main

import (
  "fmt"
  "github.com/gin-gonic/gin"
)

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

func main() {
  router := gin.Default()

  r := router.Group("/api").Use(middle)  // 可以鏈?zhǔn)?,也可以直接r.Use(middle)
  r.GET("/index", func(c *gin.Context) {
    c.String(200, "index")
  })
  r.GET("/home", func(c *gin.Context) {
    c.String(200, "home")
  })

  router.Run(":8080")
}

這樣寫我們就可以指定哪一些分組下可以使用中間件了

當(dāng)然,中間件還有一種寫法,就是使用函數(shù)加括號的形式

package main

import (
  "fmt"
  "github.com/gin-gonic/gin"
)

func middle(c *gin.Context) {
  fmt.Println("middle ...in")
}
func middle1() gin.HandlerFunc {
  // 這里的代碼是程序一開始就會執(zhí)行
  return func(c *gin.Context) {
    // 這里是請求來了才會執(zhí)行
    fmt.Println("middle1 ...inin")
  }
}

func main() {
  router := gin.Default()

  r := router.Group("/api").Use(middle, middle1())
  r.GET("/index", func(c *gin.Context) {
    c.String(200, "index")
  })
  r.GET("/home", func(c *gin.Context) {
    c.String(200, "home")
  })

  router.Run(":8080")
}

4.3 綜合使用

設(shè)置了一個中間件進(jìn)行身份驗(yàn)證,并且還對路由進(jìn)行分組,分為兩組來使用

func main() {
    r := gin.Default()

    r.Use(Logger()) // 注冊全局中間件

    v1 := r.Group("/v1")
    v1.Use(Auth()) // 注冊 v1 路由組的局部中間件
    {
        v1.GET("/hello", HelloHandler)
        v1.GET("/user", UserHandler)
    }

    r.GET("/hello", HelloHandler) // 其他路由不使用 Auth 中間件

    r.Run(":8080")
}

func Auth() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 進(jìn)行身份驗(yàn)證的邏輯

        if IsAuthenticated {
            c.Next()
        } else {
            c.AbortWithStatus(http.StatusUnauthorized)
        }
    }
}

func HelloHandler(c *gin.Context) {
    c.String(http.StatusOK, "Hello, Gin!")
}

func UserHandler(c *gin.Context) {
    c.String(http.StatusOK, "User Info")
}

// Logger 是一個全局中間件
func Logger() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()

		c.Next()

		end := time.Now()
		latency := end.Sub(start)

		log.Printf("[%s] %s %s %v", c.Request.Method, c.Request.URL.Path, c.Request.RemoteAddr, latency)
	}
}

5 使用內(nèi)置的中間件

Gin框架內(nèi)置了一些常用的中間件,可以直接使用。以下是一些常用的內(nèi)置中間件和示例:

  • gin.Logger():記錄請求日志
  • gin.Recovery():處理請求時(shí)的恢復(fù)機(jī)制
func main() {
    r := gin.Default()

    r.Use(gin.Logger()) // 使用 gin.Logger() 中間件
    r.Use(gin.Recovery()) // 使用 gin.Recovery() 中間件

    r.GET("/hello", HelloHandler)

    r.Run(":8000")
}

func HelloHandler(c *gin.Context) {
    c.String(http.StatusOK, "Hello, Gin!")
}

不過,平常我們不使用這兩個中間件的時(shí)候,一樣會有記錄,所以我們看一下gin.Default函數(shù)

func Default() *Engine {
	debugPrintWARNINGDefault()
	engine := New()
	engine.Use(Logger(), Recovery())
	return engine
}

從這段代碼就可以看出,是默認(rèn)使用了這兩個函數(shù),一般自動調(diào)用了~~~

6 中間件案例

權(quán)限驗(yàn)證

以前后端最流行的jwt為例,如果用戶登錄了,前端發(fā)來的每一次請求都會在請求頭上攜帶上token

后臺拿到這個token進(jìn)行校驗(yàn),驗(yàn)證是否過期,是否非法

如果通過就說明這個用戶是登錄過的

不通過就說明用戶沒有登錄

package main

import (
  "github.com/gin-gonic/gin"
)

func JwtTokenMiddleware(c *gin.Context) {
  // 獲取請求頭的token
  token := c.GetHeader("token")
  // 調(diào)用jwt的驗(yàn)證函數(shù)
  if token == "1234" {
    // 驗(yàn)證通過
    c.Next()
    return
  }
  // 驗(yàn)證不通過
  c.JSON(200, gin.H{"msg": "權(quán)限驗(yàn)證失敗"})
  c.Abort()
}

func main() {
  router := gin.Default()

  api := router.Group("/api")

  apiUser := api.Group("")
  {
    apiUser.POST("login", func(c *gin.Context) {
      c.JSON(200, gin.H{"msg": "登錄成功"})
    })
  }
  apiHome := api.Group("system").Use(JwtTokenMiddleware)
  {
    apiHome.GET("/index", func(c *gin.Context) {
      c.String(200, "index")
    })
    apiHome.GET("/home", func(c *gin.Context) {
      c.String(200, "home")
    })
  }

  router.Run(":8080")
}

耗時(shí)統(tǒng)計(jì)

統(tǒng)計(jì)每一個視圖函數(shù)的執(zhí)行時(shí)間文章來源地址http://www.zghlxwxcb.cn/news/detail-729240.html

func TimeMiddleware(c *gin.Context) {
  startTime := time.Now()
  c.Next()
  since := time.Since(startTime)
  // 獲取當(dāng)前請求所對應(yīng)的函數(shù)
  f := c.HandlerName()
  fmt.Printf("函數(shù) %s 耗時(shí) %d\n", f, since)
}

到了這里,關(guān)于Go學(xué)習(xí)第十七章——Gin中間件與路由的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Go Gin Gorm Casbin權(quán)限管理實(shí)現(xiàn) - 3. 實(shí)現(xiàn)Gin鑒權(quán)中間件

    Go Gin Gorm Casbin權(quán)限管理實(shí)現(xiàn) - 3. 實(shí)現(xiàn)Gin鑒權(quán)中間件

    Casbin是用于Golang項(xiàng)目的功能強(qiáng)大且高效的開源訪問控制庫。 強(qiáng)大通用也意味著概念和配置較多,具體到實(shí)際應(yīng)用(以Gin Web框架開發(fā))需要解決以下問題: 權(quán)限配置的存儲,以及 增刪改查 Gin框架的中間件如何實(shí)現(xiàn) 經(jīng)過一番摸索實(shí)踐出經(jīng)驗(yàn),計(jì)劃分為三個章節(jié),循序漸進(jìn)的介紹

    2024年02月07日
    瀏覽(22)
  • [每周一更]-(第83期):Go新項(xiàng)目-Gin中間件的使用和案例(10)

    [每周一更]-(第83期):Go新項(xiàng)目-Gin中間件的使用和案例(10)

    在 Gin 中,中間件是一種用于處理 HTTP 請求和響應(yīng)的功能強(qiáng)大的機(jī)制。中間件是一段位于請求處理鏈和最終處理器之間的代碼, 它可以截獲請求、執(zhí)行預(yù)處理操作,修改請求或響應(yīng),然后將控制權(quán)傳遞給下一個中間件或最終的請求處理器。 中間件在業(yè)務(wù)使用中,方便注入一些

    2024年01月20日
    瀏覽(26)
  • gin中間件篇

    gin中間件篇

    所有請求都經(jīng)過此中間件 輸出結(jié)果: 輸出結(jié)果: 效果演示: 定義程序計(jì)時(shí)中間件,然后定義2個路由,執(zhí)行函數(shù)后應(yīng)該打印統(tǒng)計(jì)的執(zhí)行時(shí)間,如下: 效果演示: 參考文章: https://www.fansimao.com/928855.html? gin Next()方法 - 范斯貓

    2024年01月21日
    瀏覽(25)
  • gin框架內(nèi)容(三)--中間件

    gin框架內(nèi)容(三)--中間件

    gin框架內(nèi)容(三)--中間件 Gin框架允許開發(fā)者在處理請求的過程中,加入用戶自己的函數(shù)。這個函數(shù)就叫中間件,中間件適合處理一些公共的業(yè)務(wù)邏輯,比 如登錄認(rèn)證、權(quán)限校驗(yàn)、數(shù)據(jù)分頁、記錄日志、耗時(shí)統(tǒng) 計(jì)等 即比如,如果訪問一個網(wǎng)頁的話,不管訪問什么路徑都需要

    2024年02月15日
    瀏覽(20)
  • gin框架39--重構(gòu) BasicAuth 中間件

    gin框架39--重構(gòu) BasicAuth 中間件

    每當(dāng)我們打開一個網(wǎng)址的時(shí)候,會自動彈出一個認(rèn)證界面,要求我們輸入用戶名和密碼,這種BasicAuth是最基礎(chǔ)、最常見的認(rèn)證方式,gin框架中提供了一種內(nèi)置的方式,但它只能用內(nèi)置的用戶和密碼,無法使用外部db中的用戶和密碼,這種方式很多時(shí)候是不友好的。 為此,本文

    2024年02月08日
    瀏覽(23)
  • gin中使用限流中間件

    gin中使用限流中間件

    限流又稱為流量控制(流控),通常是指限制到達(dá)系統(tǒng)的并發(fā)請求數(shù),本文列舉了常見的限流策略,并以gin框架為例演示了如何為項(xiàng)目添加限流組件。 限流又稱為流量控制(流控),通常是指限制到達(dá)系統(tǒng)的并發(fā)請求數(shù)。 我們生活中也會經(jīng)常遇到限流的場景,比如:某景區(qū)

    2024年01月25日
    瀏覽(14)
  • gin 中間件流程控制:Next()、 Abort()

    gin 中間件流程控制:Next()、 Abort()

    源碼注釋: Next 應(yīng)該只在中間件內(nèi)部使用。它執(zhí)行調(diào)用處理程序內(nèi)部鏈中的掛起處理程序。 通俗的說,就是中間件放行,當(dāng)一個中間件代碼執(zhí)行到 Next() ,會先執(zhí)行它之后的函數(shù),最后再來執(zhí)行完本函數(shù)。 eg: 如果其中一個中間件響應(yīng)了c.Abort(),后續(xù)中間件將不再執(zhí)行,直接按

    2024年02月15日
    瀏覽(36)
  • Golang中Gin 參數(shù)綁定和驗(yàn)證的中間件

    1. 學(xué)習(xí)在Golang中使用Gin參數(shù)綁定和驗(yàn)證的中間件,了解不同參數(shù)類型的綁定和驗(yàn)證方式。 Gin框架提供了很多常用的中間件,其中就包括參數(shù)綁定和驗(yàn)證的中間件。在使用Gin框架中進(jìn)行數(shù)據(jù)綁定和驗(yàn)證時(shí),可以使用Gin內(nèi)置的Binding、Validating和Uri中間件。 1. Binding Binding中間件用于

    2024年02月08日
    瀏覽(36)
  • Gin框架: 控制器, 中間件的分層設(shè)計(jì)案例

    對控制器的分組與繼承 1 )設(shè)計(jì)項(xiàng)目目錄結(jié)構(gòu) 2 )主程序 main.go 3 ) HTML模板目錄配置 tpls/web/index.html 4 ) routers 配置 4.1 webRouters.go 4.2 apiRouters.go 4.2 adminRouters.go 5 ) controller 配置 5.1 web/webCtrl.go 5.2 api/apiCtrl.go 5.3 admin/indexCtrl.go 5.4 admin/baseCtrl.go 5.4 admin/userCtrl.go 以上就是對控制器的一

    2024年02月21日
    瀏覽(24)
  • 簡單記錄下gin中使用中間件記錄操作日志

    1、直接定義中間件 2、在需要使用的地方直接使用就可以,自動會收集日志到數(shù)據(jù)庫中

    2024年02月09日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包