2016-07-21 40 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