我需要将响应主体记录在gin的中间件中,但是我找不到如何获取响应主体。有人可以帮忙吗?
我正在使用这样的中间件:
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 } } }
我的问题是,如何从中间件中的Context获取响应主体?
您需要拦截响应的编写并将其首先存储在某处。然后您可以记录它。为此,您需要实现自己的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(ginBodyLogMiddleware)
请注意,该基石不适用于静态文件,因为gin似乎没有为它们使用c.Writer。但是在大多数情况下,这仍然是您想要的。
如果要拦截所有文件,则需要使用稍微复杂一些的方法。代替中间件,您需要实现一个包装器http.Handler,该包装器将包装gin.Engine并将使用与上面所示相同的方法来拦截和记录写入http.ResponseWriter的内容。然后像这样运行gin服务器:
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}