2016-07-21 44 views
2

我需要將響應主體記錄在杜松子酒的中間件中,但我找不到如何獲取響應主體。誰能幫忙?如何在杜松子酒中記錄響應主體

我使用的是中間件這樣的:

func Logger() gin.HandlerFunc { 

    return func(c *gin.Context) { 

     c.Next() 

     statusCode := c.Writer.Status() 
     if statusCode >= 400 { 
      //ok this is an request with error, let's make a record for it 
      //log body here 
     } 
    } 
} 

我的問題是,如何在中間件場景中獲得響應的身體嗎?

+0

如果還沒有,請點擊這裏處理中提到的錯誤https://github.com/gin-gonic/gin/issues/274 – Aravind

+0

嗯,我想我明白你的意思,我應該在上下文中添加一個錯誤並在中間件中處理它,對嗎?但是我仍然對如何獲得中間件的響應機構感到好奇,如果在我將其發送回客戶端之前需要在身體上做些什麼,該怎麼辦?或者任何奇怪的要求使我必須得到響應體? –

回答

4

您需要攔截響應的寫入並將其存儲在第一個地方。然後你可以登錄它。爲此,您需要實現自己的Writer截取Write()調用。

例如,如下:

type bodyLogWriter struct { 
    gin.ResponseWriter 
    body *bytes.Buffer 
} 

func (w bodyLogWriter) Write(b []byte) (int, error) { 
    w.body.Write(b) 
    return w.ResponseWriter.Write(b) 
} 

func ginBodyLogMiddleware(c *gin.Context) { 
    blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer} 
    c.Writer = blw 
    c.Next() 
    statusCode := c.Writer.Status() 
    if statusCode >= 400 { 
     //ok this is an request with error, let's make a record for it 
     // now print body (or log in your preferred way) 
     fmt.Println("Response body: " + blw.body.String()) 
    } 
} 

然後用這個中間件這樣的:

router.Use(ginBodyLogFilter) 

注意這個門檻不會對靜態文件工作杜松子酒似乎並不用c爲他們寫文章。但在大多數情況下,這就是你想要的。

如果要截取所有文件,則需要使用稍微複雜的方法。而不是中間件,你需要實現一個封裝器http.Handler來包裝gin.Engine,並且將使用與上面所示相同的方法截取並記錄寫入http.ResponseWriter的任何內容。然後運行杜松子酒服務器這樣的:

ginRouter := gin.New() 
// configure your middleware and routes as required 

// Run http server as follows, where bodyLogHandler is your wrapper handler 
http.ListenAndServe(bindAddress, &bodyLogHandler{wrappedHandler: ginRouter} 
+0

謝謝,我明白了,作者只能寫作,所以我不能直接閱讀。 Thnaks。 –

+0

謝謝,你知道我怎麼得到帖子參數? –

+0

如果您使用的是中間件方法,您可以使用gin.Context將它們放入ginBodyLogMiddleware中,就像在實際處理程序中處理請求時一樣。您顯然無法從bodyLogWriter的Write函數中獲取它們,但您始終可以將gin.Context添加到bodyLogWriter結構中。無論如何,它爲每個請求實例化。 – Seva