2016-07-21 4 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) 

Обратите внимание, что этот подоконник не будет работать для статических файлов, как джин, кажется, не использовать гр .Writer для них. Но в большинстве случаев это то, что вы хотите в любом случае.

Если вы хотите перехватить все файлы, вам нужно использовать несколько более сложный подход. Вместо промежуточного ПО вам нужно будет внедрить оболочку 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

Если вы используете подход промежуточного программного обеспечения, вы получаете их внутри ginBodyLogMiddleware из gin.Context так же, как вы получаете их при обработке запроса в фактическом обработчике. Вы, очевидно, не можете получить их от автора ответа внутри bodyLogWriter 'Write function, но вы всегда можете добавить gin.Context в bodyLogWriter struct. Он создается для каждого запроса в любом случае. – Seva

Смежные вопросы