当前位置: 首页 > 面试题库 >

在http.HandleFunc内记录对传入HTTP请求的响应

空成天
2023-03-14
问题内容

这是In go中的后续问题,如何检查写入http.ResponseWriter的http响应因为那里的解决方案需要伪造一个请求,所以对于单元测试非常有效,但不适用于实时服务器。

我想将我的Web服务响应于从用户收到的请求而返回的HTTP响应转储到日志文件(或控制台)中。输出应该告诉我标题是什么和JSON有效负载。

如何做到这一点?

如果有一个使用http.ResponseWriter作为参数而不是http.Response的httputil.DumpResponse等效项,那将是完美的,但是目前我只能从http.ResponseWriter访问标头

r = mux.NewRouter()
r.HandleFunc("/path", func (w http.ResponseWriter, r *http.Request) {

    fmt.Printf("r.HandleFunc /path\n")

    resp := server.NewResponse()
    defer resp.Close()

    r.ParseForm()

    // Server does some work here
    // ...

    // Insert debug code here, something like
    //
    // dump = http.DumpResponseFromWriter(w)
    // fmt.Printf("%s\n", dump)
});
http.Handle("/path", r)

问题答案:

一个常见的解决方案是所谓的 中间件链
。有几个提供此功能的库,例如negroni。

这是一种连续传递样式的形式,您可以像这样编写 中间件 功能(取自negroni的自述文件):

func MyMiddleware(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
  // do some stuff before
  next(rw, r)
  // do some stuff after
}

然后negroni为您提供一个HTTP处理程序,该处理程序以正确的顺序调用您的中间件。

我们可以略有不同实施这一方案,以较少的神奇和更多的功能(如 函数式编程 )的方式。定义处理程序组合器,如下所示:

func NewFooHandler(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // do some stuff before
        next(r,w)
        // do some stuff after
    }
}

然后将您的链定义为组合:

h := NewFooHandler(NewBarHandler(NewBazHandler(Sink)))

现在h是一个http.HandlerFunc执行foo,然后执行bar,然后执行baz的操作。Sink只是一个空的最后一个处理程序,不执行任何操作(以“完成”链)。

将此解决方案应用于您的问题

定义一个处理程序组合器:

func NewResponseLoggingHandler(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {

        // switch out response writer for a recorder
        // for all subsequent handlers
        c := httptest.NewRecorder()
        next(c, r)

        // copy everything from response recorder
        // to actual response writer
        for k, v := range c.HeaderMap {
            w.Header()[k] = v
        }
        w.WriteHeader(c.Code)
        c.Body.WriteTo(w)

    }
}

现在问题归结为处理程序管理。您可能希望将此处理程序应用于某个类别中的所有链。为此,您可以再次使用组合器(这与negroni的Classic()方法相当):

func NewDefaultHandler(next http.HandlerFunc) http.HandlerFunc {
    return NewResponseLoggingHandler(NewOtherStuffHandler(next))
}

之后,无论何时启动这样的链:

h := NewDefaultHandler(...)

它将自动包括响应日志记录和您在中定义的所有默认内容NewDefaultHandler



 类似资料:
  • 在Vertx WebClient中记录传出http请求和响应的最简单方法是什么。我正在寻找类似于httpserver LoggerHandler的东西,但接下来是webclient的输出请求。

  • 使用Netty 4.0.0.beta1,对我来说,将传入/传出HTTP流量记录到基于Netty的服务器的最佳方式是什么?我的管道当前为: 我尝试编写一个实现的处理程序,然后在方法中进行日志记录,这似乎对传入的请求很好,但这是推荐的方式吗? 当我试图实现时,我未能在方法中看到实际的FullHttpResponse对象。 建议?谢了!

  • 我试图通过aop在控制器中记录超文本传输协议请求。但是,在方面代码中,如果我 那么请求数据将无法在主流中检索。 所以,我创建了另一个公共方法,在控制器中传递请求字符串 这种方法是记录“数据”的切入点。 但问题是,这种方法的切入点似乎无法通过Spring识别,这种方法没有日志记录。我需要帮助。 下面是aop的定义

  • 我在雄猫上部署了一个泽西岛 2.5.1 应用程序。我在我的网络中添加了以下配置.xml: 它打印请求和响应头。但是,它没有在响应中打印请求/响应实体/主体。 我试着和不同的情妇玩,但没有运气,比如: 感谢您的回答。看起来我在上面粘贴了错误的配置。这是我在我的网络上有什么.xml: 它记录标题。但它不记录实体。这是我在日志中看到的: 我的Jersey应用程序部署在Tomcat 7_50服务器上。 如

  • 我正在使用Spring Boot 1.1.5构建一个web应用程序。我已经按照相关Spring Boot文档中的描述配置了一个嵌入式Jetty。 我想记录所有传入的HTTP请求,我能想到的唯一解决方案(在读了Spring Boot文档中的“如何配置Jetty”之后)是引入EmbeddedServletContainerCustomizer: 应用程序现在无法开始引发异常: java.lang.Il

  • 我是spring cloud gateway的新手,我希望将传入的请求记录到相应的路由url,例如,如果我有以下路由配置: 是否有任何简单的方法来实现这一点,或者我可以实现这只是通过设置日志级别。 你能帮忙吗