如何在 golang 中间件中获取响应状态码?

hua*_*ple 6 go

如何在 golang 中间件中获取响应状态码?

ResponseWriter 只有 WriteHeader 接口,我找不到 get 接口。

Kar*_*lek 9

使用内格罗尼。它的工作原理与 @huangapple 答案相同,但处理程序实际上实现了所有接口。

import (
    "github.com/urfave/negroni"
)

func wrapHandlerWithLogging(wrappedHandler http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
        log.Printf("--> %s %s", req.Method, req.URL.Path)

        lrw := negroni.NewResponseWriter(w)
        wrappedHandler.ServeHTTP(lrw, req)

        statusCode := lrw.Status()
        log.Printf("<-- %d %s", statusCode, http.StatusText(statusCode))
    })
}
Run Code Online (Sandbox Code Playgroud)


hua*_*ple 6

这种方法是可行的。

    type loggingResponseWriter struct {
        http.ResponseWriter
        statusCode int
    }

    func NewLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter {
        return &loggingResponseWriter{w, http.StatusOK}
    }

    func (lrw *loggingResponseWriter) WriteHeader(code int) {
        lrw.statusCode = code
        lrw.ResponseWriter.WriteHeader(code)
    }

    func wrapHandlerWithLogging(wrappedHandler http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
            log.Printf("--> %s %s", req.Method, req.URL.Path)

            lrw := NewLoggingResponseWriter(w)
            wrappedHandler.ServeHTTP(lrw, req)

            statusCode := lrw.statusCode
            log.Printf("<-- %d %s", statusCode, http.StatusText(statusCode))
        })
    }
Run Code Online (Sandbox Code Playgroud)

  • 但这种方法确实存在一些问题。它将中断所有额外接口的使用 - Flusher、Pusher、CloseNotifier 和 Hijacker。 (3认同)

Ole*_*leg 6

长话短说,您应该自己包装 http.ResponseWriter 或使用库。如果你想自己实现,可以从Negroni源代码中找到一些提示