校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > 如何編寫Go語言中間件的實例教程

如何編寫Go語言中間件的實例教程

熱門標簽:鄭州亮點科技用的什么外呼系統 阿里云ai電話機器人 釘釘有地圖標注功能嗎 浙江高頻外呼系統多少錢一個月 濱州自動電銷機器人排名 建造者2地圖標注 黃岡人工智能電銷機器人哪個好 惠州電銷防封電話卡 汕頭小型外呼系統

引言

web開發的背景下,“中間件”通常意思是“包裝原始應用并添加一些額外的功能的應用的一部分”。這個概念似乎總是不被人理解,但是我認為中間件非常棒。

首先,一個好的中間件有一個責任就是可插拔并且自足。這就意味著你可以在接口級別嵌入你的中間件他就能直接運行。它不會影響你編碼方式,不是框架,僅僅是你請求處理里面的一層而已。完全沒必要重寫你的代碼,如果你想使用中間件的一個功能,你就幫他插入到那里,如果不想使用了,就可以直接移除。

縱觀Go語言,中間件是非常普遍的,即使在標準庫中。雖然開始的時候不會那么明顯,在標準庫net/http中的函數StripText或者TimeoutHandler就是我們要定義和的中間件的樣子,處理請求和相應的時候他們包裝你的handler,并處理一些額外的步驟。

一開始,我們認為編寫中間件似乎很容易,但是我們實際編寫的時候也會遇到各種各樣的坑。讓我們來看看一些例子。

1、讀取請求

在我們的示例中,所有的中間件都將接受http。處理程序作為一個參數,并返回一個http.Handler。這使得人們很容易就能把中間產品串起來。我們所有的中間產品的基本模式是這樣的:

func X(h http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 // Something here...
 h.ServeHTTP(w, r)
 })
}

我們想要將所有的請求重定向到一個斜杠——比方說/message/,到它們的非斜杠等效,比如/message。我們可以這樣寫:

func TrailingSlashRedirect(h http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 if r.URL.Path != "/"  r.URL.Path[len(r.URL.Path)-1] == '/' {
 http.Redirect(w, r, r.URL.Path[:len(r.URL.Path)-1], http.StatusMovedPermanently)
 return
 }
 h.ServeHTTP(w, r)
 })
}

有沒有很簡單。

2、修改請求

比方說,我們想要向請求添加一個標題,或者修改它。http.Handler文檔中指明:

除了讀取主體之外,處理程序不應該修改所提供的請求。

Go標準庫復制http.Request。請求對象在將其傳遞到響應鏈之前,我們也應該這樣做。假設我們想在每個請求上設置Request-Id頭,以便內部跟蹤。創建*Request的淺副本,并在代理之前修改標題。

func RequestID(h http.Handler) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 r2 := new(http.Request)
 *r2 = *r
 r2.Header.Set("X-Request-Id", uuid.NewV4().String())
 h.ServeHTTP(w, r2)
 })
}

3、編寫響應頭

如果你想設置響應頭,你可以只寫它們,然后代理請求。

func Server(h http.Handler, servername string) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Server", servername)
 h.ServeHTTP(w, r)
 })
}

上面的問題是,如果內部處理器也設置了服務器頭,那么你的頭將被覆蓋。如果不想公開內部軟件的服務器頭,或者如果想在發送響應給客戶端之前去掉頭部,這可能會帶來問題。

要做到這一點,我們必須自己實現ResponseWriter接口。大多數時候,我們只會代理到底層的ResponseWriter,但是如果用戶試圖寫一個響應,我們就會潛入并添加我們的標題。

type serverWriter struct {
 w http.ResponseWriter
 name string
 wroteHeaders bool
}

func (s *serverWriter) Header() http.Header {
 return s.w.Header()
}

func (s *serverWriter) WriteHeader(code int) http.Header {
 if s.wroteHeader == false {
 s.w.Header().Set("Server", s.name)
 s.wroteHeader = true
 }
 s.w.WriteHeader(code)
}

func (s *serverWriter) Write(b []byte) (int, error) {
 if s.wroteHeader == false {
 // We hit this case if user never calls WriteHeader (default 200)
 s.w.Header().Set("Server", s.name)
 s.wroteHeader = true
 } return s.w.Write(b)
}

要在我們的中間件中使用它,我們會寫:

func Server(h http.Handler, servername string) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 sw := serverWriter{
 w: w,
 name: servername,
 }
 h.ServeHTTP(sw, r)
 })
}

問題

如果用戶從不調用Write或WriteHeader呢?例如,有一個200狀態并且是空body,或者對選項請求的響應——我們的攔截函數都不會運行。因此,我們應該在ServeHTTP調用之后再添加校驗。

func Server(h http.Handler, servername string) http.Handler {
 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 sw := serverWriter{
 w: w,
 name: servername,
 }
 h.ServeHTTP(sw, r)
 if sw.wroteHeaders == false {
 s.w.Header().Set("Server", s.name)
 s.wroteHeader = true
 }
 })
}

其他ResponseWriter接口

ResponseWriter接口只需要有三種方法。但在實踐中,它也可以對其他接口作出響應,例如http.Pusher。你的中間件可能會意外地禁用HTTP/2支持,這是不好的。

// Push implements the http.Pusher interface.
func (s *serverWriter) Push(target string, opts *http.PushOptions) error {
 if pusher, ok := s.w.(http.Pusher); ok {
 return pusher.Push(target, opts)
 }
 return http.ErrNotSupported
}

// Flush implements the http.Flusher interface.
func (s *serverWriter) Flush() {
 f, ok := s.w.(http.Flusher)
 if ok {
 f.Flush()
 }
}

總結

通過以上的學習,不知道大家對Go編寫中間件有沒有一個完整的認識。大家也可以嘗試著用Go去編寫一個中間件。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

標簽:晉中 滄州 昭通 駐馬店 東營 阿壩 瀘州 泰安

巨人網絡通訊聲明:本文標題《如何編寫Go語言中間件的實例教程》,本文關鍵詞  如何,編寫,語言,中間件,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《如何編寫Go語言中間件的實例教程》相關的同類信息!
  • 本頁收集關于如何編寫Go語言中間件的實例教程的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    久久久久久久久岛国免费| 日本韩国一区二区三区视频| 午夜久久福利影院| 亚洲一区二区免费视频| 亚洲国产精品久久艾草纯爱 | 奇米一区二区三区| 亚洲综合偷拍欧美一区色| 亚洲主播在线观看| 日日噜噜夜夜狠狠视频欧美人 | 2021久久国产精品不只是精品| 日韩欧美综合一区| 精品裸体舞一区二区三区| 欧美videos中文字幕| 国产人成一区二区三区影院| 国产精品福利一区二区三区| 日韩伦理免费电影| 视频一区二区三区入口| 蜜臂av日日欢夜夜爽一区| 国产精品香蕉一区二区三区| 色哟哟一区二区三区| 91精品免费观看| 精品欧美乱码久久久久久| 国产精品久久毛片a| 亚洲最大成人网4388xx| 日本不卡一二三区黄网| 懂色av一区二区三区免费观看| 一本久道久久综合中文字幕 | 国产一区二区三区| 91亚洲国产成人精品一区二区三| 欧美色图天堂网| 欧美成人国产一区二区| 中文字幕在线一区| 麻豆精品视频在线| 91农村精品一区二区在线| 日韩一区二区视频在线观看| 国产精品素人视频| 伦理电影国产精品| 色婷婷激情综合| 国产午夜精品福利| 亚洲成人免费在线观看| 国产99久久久国产精品潘金| 91.麻豆视频| 亚洲欧洲国产日韩| 精品一区二区三区视频| 欧美性一二三区| 一区在线中文字幕| 久久91精品国产91久久小草| 色综合中文字幕国产| 欧美一区二区三区视频在线| 亚洲欧洲制服丝袜| 国产美女娇喘av呻吟久久| 欧美日韩1234| 亚洲欧美一区二区三区极速播放 | 日本一区二区成人在线| 日本欧美韩国一区三区| 欧美天堂一区二区三区| 17c精品麻豆一区二区免费| 国内精品不卡在线| 欧美精品自拍偷拍| 亚洲高清视频在线| 91黄色免费版| 亚洲婷婷综合久久一本伊一区| 国产黄人亚洲片| 26uuu另类欧美亚洲曰本| 久久99精品网久久| 日韩色在线观看| 男男视频亚洲欧美| 欧美一区二区三区小说| 午夜不卡在线视频| 欧美久久久久中文字幕| 婷婷综合在线观看| 欧美疯狂做受xxxx富婆| 性感美女极品91精品| 欧美性感一类影片在线播放| 一个色综合av| 欧美日韩国产高清一区二区三区| 亚洲一级在线观看| 欧美精品丝袜中出| 日日摸夜夜添夜夜添亚洲女人| 91精品免费在线| 精品系列免费在线观看| 欧美精品一区二区三区蜜桃| 国内精品写真在线观看| 久久久久久日产精品| 国产成人综合在线| 亚洲视频一二三| 欧美性猛交xxxxxxxx| 免费在线观看精品| 久久久国产一区二区三区四区小说| 久久9热精品视频| 亚洲国产精品高清| 在线一区二区三区四区| 日韩中文字幕区一区有砖一区 | 91色porny在线视频| 亚洲一区二区欧美| 日韩欧美电影一二三| 国产福利一区二区三区视频在线| 久久久99久久| 91国产视频在线观看| 日本不卡一区二区三区高清视频| 欧美精品一区二区在线观看| 不卡一区在线观看| 午夜电影久久久| 中文乱码免费一区二区| 欧美在线观看你懂的| 国内久久婷婷综合| 亚洲综合av网| 精品88久久久久88久久久 | 性久久久久久久久久久久| 精品国精品国产| 在线观看三级视频欧美| 久久精品国产在热久久| 中文字幕中文字幕在线一区| 日韩精品综合一本久道在线视频| 波多野结衣中文一区| 日韩成人免费在线| 亚洲另类一区二区| 国产亚洲自拍一区| 欧美二区三区的天堂| 91丨porny丨蝌蚪视频| 久久成人综合网| 亚洲大型综合色站| 亚洲视频一区二区免费在线观看| 精品国产乱码久久久久久夜甘婷婷| 91香蕉视频在线| 国产成人av电影在线播放| 日韩福利电影在线| 午夜亚洲国产au精品一区二区| 国产精品久久久久久久久免费桃花| 亚洲欧洲性图库| 欧美日韩精品三区| 日本道在线观看一区二区| 黄一区二区三区| 喷水一区二区三区| 亚洲精品欧美在线| 国产精品嫩草99a| 久久婷婷成人综合色| 在线成人免费观看| 91国产成人在线| 91免费看视频| 99re这里只有精品6| 国产成人在线色| 狠狠色丁香久久婷婷综合_中| 日一区二区三区| 一区二区三区日韩精品视频| 国产精品丝袜一区| 国产精品国产馆在线真实露脸| 久久久亚洲国产美女国产盗摄| 欧美不卡123| 2022国产精品视频| 久久久青草青青国产亚洲免观| 日韩精品一区二区三区四区视频| 欧美巨大另类极品videosbest | 欧美亚洲一区二区在线| 在线亚洲精品福利网址导航| 日本乱人伦一区| 色婷婷av久久久久久久| 欧美日韩国产综合草草| 欧美日韩一区二区三区免费看| 欧美在线视频不卡| 欧美一区永久视频免费观看| 91精品一区二区三区久久久久久| 9191国产精品| 国产午夜精品久久久久久久| 中文字幕五月欧美| 亚洲一区二区三区中文字幕| 爽爽淫人综合网网站| 日韩电影一区二区三区| 国产一区二区三区综合| 成人教育av在线| 色婷婷av一区二区三区大白胸| 欧美日韩精品专区| 欧美成人午夜电影| 国产精品久久久久四虎| 亚洲一区在线电影| 蜜桃视频一区二区三区在线观看| 国产91高潮流白浆在线麻豆| 在线观看日韩电影| 日韩欧美国产午夜精品| 国产精品入口麻豆原神| 亚洲成a人片在线不卡一二三区| 日韩精品免费视频人成| 国产成人午夜片在线观看高清观看| 成人黄色片在线观看| 欧美日韩免费不卡视频一区二区三区 | 老司机精品视频导航| 成人国产在线观看| 日韩一区二区中文字幕| 国产精品成人一区二区艾草 | 亚洲日本在线天堂| 蜜桃91丨九色丨蝌蚪91桃色| aaa亚洲精品| 日韩片之四级片| 夜夜嗨av一区二区三区四季av| 国内偷窥港台综合视频在线播放| 色综合天天综合狠狠| 欧美成人福利视频| 亚瑟在线精品视频| 99re6这里只有精品视频在线观看| 欧美一区二区三区免费观看视频|