欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解Go gin框架中Context的Request和Writer對象

 更新時間:2023年04月23日 09:23:17   作者:Go學堂  
這篇文章主要為大家詳細介紹了Go語言的gin框架中Context的Request和Writer對象,文中的示例代碼講解詳細,對我們深入了解Go語言有一定的幫助,快跟隨小編一起學習一下吧

背景

在使用gin框架時,我們定義的請求處理器,輸入?yún)?shù)總是一個gin.Context的指針類型,代表請求的上下文。在處理器的業(yè)務邏輯中,通過Context.Request可以獲取本次請求的參數(shù)值;通過Context.Writer就能將響應結果輸出給客戶端了。如下代碼所示:

package main

import (
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
)

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

    // 注冊路由,定義請求處理器函數(shù)
	r.GET("/", func(c *gin.Context) {
        c.Param
		c.Writer.Write([]byte("Hello World"))

	})

  // 調(diào)用該函數(shù),則禁用日志帶顏色輸出
	gin.DisableConsoleColor()
  
  //使用該函數(shù),則強制日志帶顏色輸出,無論是在終端還是其他輸出設備 
	gin.ForceConsoleColor()

	r.Run("127.0.0.1:8080")
}

那么,Context字段是在什么地方初始化的呢,為什么通過Context.Request字段就能讀取請求的參數(shù)呢,又為什么通過Context.Writer字段就能將響應結果輸出給客戶端呢?接下來我們就一一解答這3個問題。

Context對象的初始化

gin的Context對象實際上是在Engine對象的ServeHTTP函數(shù)中進行初始化的,如下:

// ServeHTTP conforms to the http.Handler interface.
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	c := engine.pool.Get().(*Context)
	c.writermem.reset(w)
	c.Request = req
	c.reset()

	engine.handleHTTPRequest(c)

	engine.pool.Put(c)
}

通過該函數(shù)我們可以看到,在第3行通過池化技術獲取到一個新的Context對象。獲取到該Context后,通過engine.handleHTTPRequest函數(shù)傳入Context參數(shù),進而找到對應的路由處理器,傳遞給具體的路由處理器。在上例中就是r.GET中的對應處理器。

在這個函數(shù)中,還會把本次的請求體req賦值給Context.Request變量。這樣,在具體的請求處理器中就可以通過Context的各種方法從Request中獲取參數(shù)值了。比如GetHeader、GetRawData等。

我們再來回顧下go的http的啟動和請求處理流程,以便了解ServeHTTP的調(diào)用時機。engine對象實際上是實現(xiàn)了go的標準包中的Handler接口。該接口中定義了ServeHTTP方法。在接收到請求后,net/http的包就會調(diào)用engine的ServeHTTP方法。如下圖中的engine.ServeHTTP部分:

Context.Request對象

在上節(jié)中,在Engine的ServeHTTP函數(shù)中,將函數(shù)的入?yún)eq賦值給了Context的Request對象。那么,這個req變量對象是從哪里來的呢?

Engine.ServeHTTP函數(shù)是在net/http/server.go文件的conn.serve函數(shù)中被調(diào)用的。conn代表本次請求的連接對象。conn.serve函數(shù)首先會從conn對象中讀取出本次的請求參數(shù)(包含請求頭等),并解析到request對象中,將該對象再賦值給Context中的Request字段。這樣,通過Context的Param、Form、Header等函數(shù),就可以從Request中讀取信息了。

Context.Writer對象

在具體的請求處理函數(shù)中,我們發(fā)現(xiàn)所有的輸出都是通過Context.Writer對象的Write函數(shù)將數(shù)據(jù)返回給客戶端的。那么,這里的Context.Writer對象是什么呢,為什么通過Context.Writer就是能結果返回給客戶端呢?

要回答這個問題,我們還需要回到net/http/server.go文件的conn.serve函數(shù)中,response參數(shù)是在該函數(shù)中調(diào)用ServeHTTP時傳入的參數(shù),而該response參數(shù)是通過conn.readRequest函數(shù)返回的。

我們再通過readRequest函數(shù)來看下response結構體的關鍵字段,如下:

我們再來看Engine.ServeHTTP函數(shù): 首先,將response對象賦值給Context.writermem對象。即在c.writermem.reset(w)函數(shù)中執(zhí)行的。 其次,Context.Writer是對Context.writermem的引用。即Context.Writer依然是指向response對象。即在c.reset()函數(shù)中執(zhí)行的。

所以,在Context中跟response有關的關鍵字段如下:

最后,在業(yè)務邏輯中使用Context.Writer.Write函數(shù)輸出時,實際上是執(zhí)行的response.Write函數(shù)。

我們再來看下response.Write函數(shù)的實現(xiàn):

寫入的時候是調(diào)用的responsew字段寫入的。那w字段又是什么呢?我們再回到server.go中的對response初始化的readRequest函數(shù)中,如下:

可以看到wresponse的對象。同時將w還賦值給了w.cw.res。最后,w.w字段是基于w.cw的一個bufio.Writer對象。當調(diào)用bufio.WriterFlush時,實際上是調(diào)用了bufio.Writer中的wrWrite方法。而wr的又是指向了chunkWriter對象的Write方法。最后該方法是執(zhí)行了w.conn.bufw.Write寫入了數(shù)據(jù)。

最終的寫入流程如下:

總結

本文深入分析了gin框架中Context中讀取請求中的數(shù)據(jù)以及寫入響應數(shù)據(jù)的原理。本質(zhì)上Request的數(shù)據(jù)來源于conn對象。最終也是寫入到conn對象的bufw中。

以上就是深入理解Go gin框架中Context的Request和Writer對象的詳細內(nèi)容,更多關于Go gin框架Context的資料請關注腳本之家其它相關文章!

相關文章

  • 解決golang編譯提示dial tcp 172.217.160.113:443: connectex: A connection attempt failed(推薦)

    解決golang編譯提示dial tcp 172.217.160.113:443: con

    這篇文章主要介紹了解決golang編譯提示dial tcp 172.217.160.113:443: connectex: A connection attempt failed,此問題完美解決,需要的朋友可以參考下
    2023-02-02
  • Go語言文件讀寫操作案例詳解

    Go語言文件讀寫操作案例詳解

    這篇文章主要為大家介紹了Go語言文件讀寫操作案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • 深入解析Golang中JSON的編碼與解碼

    深入解析Golang中JSON的編碼與解碼

    隨著互聯(lián)網(wǎng)的快速發(fā)展和數(shù)據(jù)交換的廣泛應用,各種數(shù)據(jù)格式的處理成為軟件開發(fā)中的關鍵問題,本文將介紹?Golang?中?JSON?編碼與解碼的相關知識,幫助大家了解其基本原理和高效應用,需要的可以收藏一下
    2023-05-05
  • Golang flag包的具體使用

    Golang flag包的具體使用

    本文主要介紹了Golang flag包的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • Goland 關閉自動移除未使用的包操作

    Goland 關閉自動移除未使用的包操作

    這篇文章主要介紹了Goland 關閉自動移除未使用的包操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言中并發(fā)的工作原理

    Go語言中并發(fā)的工作原理

    本文詳細講解了Go語言中并發(fā)的工作原理,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • 手把手教你導入Go語言第三方庫

    手把手教你導入Go語言第三方庫

    本文主要介紹了手把手教你導入Go語言第三方庫,通過導入gin包來深入學習,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • GO實現(xiàn)跳躍表的示例詳解

    GO實現(xiàn)跳躍表的示例詳解

    跳表全稱叫做跳躍表,簡稱跳表,是一個隨機化的數(shù)據(jù)結構,實質(zhì)就是一種可以進行二分查找的有序鏈表。本文將利用GO語言編寫一個跳表,需要的可以參考一下
    2022-12-12
  • Golang中的強大Web框架Fiber詳解

    Golang中的強大Web框架Fiber詳解

    在不斷發(fā)展的Web開發(fā)領域中,選擇正確的框架可以極大地影響項目的效率和成功,介紹一下Fiber,這是一款令人印象深刻的Golang(Go語言)Web框架,在本文中,我們將深入了解Fiber的世界,探討其獨特的特性,并理解為什么它在Go生態(tài)系統(tǒng)中引起了如此大的關注
    2023-10-10
  • 如何使用?Go?和?Excelize?構建電子表格

    如何使用?Go?和?Excelize?構建電子表格

    這篇文章主要介紹了如何使用Go和Excelize構建電子表格,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09

最新評論