欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報(bào)激活碼778899分享:Gin中間件

柚子快報(bào)激活碼778899分享:Gin中間件

http://yzkb.51969.com/

Gin框架允許開發(fā)者在處理請求的過程中,加入用戶自己的鉤子(Hook)函數(shù)。這個鉤子函數(shù)就叫中間件,中間件適合處理一些公共的業(yè)務(wù)邏輯,比如登錄認(rèn)證、權(quán)限校驗(yàn)、數(shù)據(jù)分頁、記錄日志、耗時統(tǒng)計(jì)等。

定義中間件

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

記錄接口耗時的中間件

例如我們像下面的代碼一樣定義一個統(tǒng)計(jì)請求耗時的中間件。

// StatCost 是一個統(tǒng)計(jì)耗時請求耗時的中間件

func StatCost() gin.HandlerFunc {

return func(c *gin.Context) {

start := time.Now()

c.Set("name", "小王子") // 可以通過c.Set在請求上下文中設(shè)置值,后續(xù)的處理函數(shù)能夠取到該值

// 調(diào)用該請求的剩余處理程序

c.Next()

// 不調(diào)用該請求的剩余處理程序

// c.Abort()

// 計(jì)算耗時

cost := time.Since(start)

log.Println(cost)

}

}

記錄響應(yīng)體的中間件

我們有時候可能會想要記錄下某些情況下返回給客戶端的響應(yīng)數(shù)據(jù),這個時候就可以編寫一個中間件來搞定。

type bodyLogWriter struct {

gin.ResponseWriter // 嵌入gin框架ResponseWriter

body *bytes.Buffer // 我們記錄用的response

}

// Write 寫入響應(yīng)體數(shù)據(jù)

func (w bodyLogWriter) Write(b []byte) (int, error) {

w.body.Write(b) // 我們記錄一份

return w.ResponseWriter.Write(b) // 真正寫入響應(yīng)

}

// ginBodyLogMiddleware 一個記錄返回給客戶端響應(yīng)體的中間件

// https://stackoverflow.com/questions/38501325/how-to-log-response-body-in-gin

func ginBodyLogMiddleware(c *gin.Context) {

blw := &bodyLogWriter{body: bytes.NewBuffer([]byte{}), ResponseWriter: c.Writer}

c.Writer = blw // 使用我們自定義的類型替換默認(rèn)的

c.Next() // 執(zhí)行業(yè)務(wù)邏輯

fmt.Println("Response body: " + blw.body.String()) // 事后按需記錄返回的響應(yīng)

}

跨域中間件cors

推薦使用社區(qū)的GitHub - gin-contrib/cors: Official CORS gin's middleware?庫,一行代碼解決前后端分離架構(gòu)下的跨域問題。

注意:?該中間件需要注冊在業(yè)務(wù)處理函數(shù)前面。

這個庫支持各種常用的配置項(xiàng),具體使用方法如下。

package main

import (

"time"

"github.com/gin-contrib/cors"

"github.com/gin-gonic/gin"

)

func main() {

router := gin.Default()

// CORS for https://foo.com and https://github.com origins, allowing:

// - PUT and PATCH methods

// - Origin header

// - Credentials share

// - Preflight requests cached for 12 hours

router.Use(cors.New(cors.Config{

AllowOrigins: []string{"https://foo.com"}, // 允許跨域發(fā)來請求的網(wǎng)站

AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, // 允許的請求方法

AllowHeaders: []string{"Origin", "Authorization", "Content-Type"},

ExposeHeaders: []string{"Content-Length"},

AllowCredentials: true,

AllowOriginFunc: func(origin string) bool { // 自定義過濾源站的方法

return origin == "https://github.com"

},

MaxAge: 12 * time.Hour,

}))

router.Run()

}

當(dāng)然你可以簡單的像下面的示例代碼那樣使用默認(rèn)配置,允許所有的跨域請求。

func main() {

router := gin.Default()

// same as

// config := cors.DefaultConfig()

// config.AllowAllOrigins = true

// router.Use(cors.New(config))

router.Use(cors.Default())

router.Run()

}

注冊中間件

在gin框架中,我們可以為每個路由添加任意數(shù)量的中間件。

為全局路由注冊

func main() {

// 新建一個沒有任何默認(rèn)中間件的路由

r := gin.New()

// 注冊一個全局中間件

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()

}

為某個路由單獨(dú)注冊

// 給/test2路由單獨(dú)注冊中間件(可注冊多個)

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) {...})

...

}

中間件注意事項(xiàng)

gin默認(rèn)中間件

gin.Default()默認(rèn)使用了Logger和Recovery中間件,其中:

Logger中間件將日志寫入gin.DefaultWriter,即使配置了GIN_MODE=release。Recovery中間件會recover任何panic。如果有panic的話,會寫入500響應(yīng)碼。

如果不想使用上面兩個默認(rèn)的中間件,可以使用gin.New()新建一個沒有任何默認(rèn)中間件的路由。

gin中間件中使用goroutine

當(dāng)在中間件或handler中啟動新的goroutine時,不能使用原始的上下文(c *gin.Context),必須使用其只讀副本(c.Copy())。

運(yùn)行多個服務(wù)

我們可以在多個端口啟動服務(wù),例如:

package main

import (

"log"

"net/http"

"time"

"github.com/gin-gonic/gin"

"golang.org/x/sync/errgroup"

)

var (

g errgroup.Group

)

func router01() http.Handler {

e := gin.New()

e.Use(gin.Recovery())

e.GET("/", func(c *gin.Context) {

c.JSON(

http.StatusOK,

gin.H{

"code": http.StatusOK,

"error": "Welcome server 01",

},

)

})

return e

}

func router02() http.Handler {

e := gin.New()

e.Use(gin.Recovery())

e.GET("/", func(c *gin.Context) {

c.JSON(

http.StatusOK,

gin.H{

"code": http.StatusOK,

"error": "Welcome server 02",

},

)

})

return e

}

func main() {

server01 := &http.Server{

Addr: ":8080",

Handler: router01(),

ReadTimeout: 5 * time.Second,

WriteTimeout: 10 * time.Second,

}

server02 := &http.Server{

Addr: ":8081",

Handler: router02(),

ReadTimeout: 5 * time.Second,

WriteTimeout: 10 * time.Second,

}

// 借助errgroup.Group或者自行開啟兩個goroutine分別啟動兩個服務(wù)

g.Go(func() error {

return server01.ListenAndServe()

})

g.Go(func() error {

return server02.ListenAndServe()

})

if err := g.Wait(); err != nil {

log.Fatal(err)

}

}

柚子快報(bào)激活碼778899分享:Gin中間件

http://yzkb.51969.com/

文章來源

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19332986.html

發(fā)布評論

您暫未設(shè)置收款碼

請?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄