如何在 WebClient 上记录“真实”的 Http 标头

Rub*_*ace 1 spring netty project-reactor reactor-netty spring-webflux

我目前正在使用ExchangeFilterFunction记录进入ClientRequest实例内的所有标头,我正在访问它们做request.headers().

执行我的过滤器后,HttpClient下面会添加某些标头,例如那个标头Accept-Encoding,因此不会被记录,因为它们永远不会被添加到ClientRequest实例中。

我的过滤器看起来像这样:

public class WebClientLoggingFilter implements ExchangeFilterFunction {

    @Override
    public Mono<ClientResponse> filter(final ClientRequest clientRequest, final ExchangeFunction next) {
         return Mono.just(clientRequest)
               .doOnNext(request -> log(request.headers().toString()))
               .flatMap(next::exchange)
               .doOnNext(clientResponse -> logData(clientRequestData, message, clientResponse));
  } 
}
Run Code Online (Sandbox Code Playgroud)

此过滤器将所有内容记录在ClientRequest标头中,但随后HttpClient会发挥其魔力,即使在响应返回之后,它也永远不会到达 ClientRequest。来自 Netty的代码示例

有没有其他方法可以进行日志记录,以便我可以访问真正通过网络发送的内容?

Mic*_*rry 6

我建议使用标准记录器,而不是使用过滤器,将这些行添加到您的resources/application.properties

spring.http.log-request-details=true
logging.level.org.springframework.web.reactive.function.client.ExchangeFunctions=TRACE
Run Code Online (Sandbox Code Playgroud)

但是,默认情况下,这仍将标头显示为{headers masked}(因为它们可能包含敏感数据)。要为客户端启用标头日志记录,您必须在每个客户端上显式启用它WebClient,如下所示:

return WebClient
        .builder()
        .exchangeStrategies(ExchangeStrategies.builder().codecs(c ->
                c.defaultCodecs().enableLoggingRequestDetails(true)).build()
        )
        .build()
        //carry on using the webclient as normal
Run Code Online (Sandbox Code Playgroud)

然后,您将获得类似于以下内容的输出:

HTTP POST https://a.com/ea, headers=[Content-Type:"application/json", Accept:"application/json", Authorization:"Bearer token blah"]
Run Code Online (Sandbox Code Playgroud)