【问题标题】:WebClient Request and Response body loggingWebClient 请求和响应正文记录
【发布时间】:2021-07-21 19:46:45
【问题描述】:

我正在尝试根据进行 WebClient 调用时收到的请求和响应数据来创建 POJO。但我没有以字符串/JSON 可读形式获取请求正文,而是获取了 BodyInsertor。我正在使用 Exchange 过滤器。

public ExchangeFilterFunction logWebRequest() {
    return (request, next) -> {
      log.info("Entered in logWebRequest for WebClient");
      long startTime = System.currentTimeMillis();
      Mono<ClientResponse> response = next.exchange(request);
      long processingTimeInMs = System.currentTimeMillis() - startTime;

      // request.body() -> Gives Body Insertor

      WebRequestLog webRequestLog = webRequestService.makeWebRequestLog(request, response.block());
      webRequestLog.setProcessingTimeInMs(processingTimeInMs);

      log.info("WebRequest to be produced to kafka topic: " + webRequestLog);
      kafkaService.produceAuditLog(webRequestLog);
      return response;
    };
  }

我关注了一些文章,例如 https://andrew-flower.com/blog/webclient-body-logginghttps://www.gitmemory.com/issue/spring-projects/spring-framework/24262/570245788,但对我没有任何帮助。

我的最终目标是用他们的身体捕获请求和响应,并生成为 Kafka 收集的数据。

【问题讨论】:

  • 您的问题与 Spring Kafka 完全无关。请在为您的问题选择标签时小心。

标签: java spring spring-boot logging


【解决方案1】:

在 ExchangeFilterFunction 中,您可以访问 HTTP 方法、URL、标头、cookie,但不能直接从该过滤器访问请求或响应正文。

参考答案here。它提供了一种访问请求和响应正文的方法。它还提供了指向This blog post 的链接。它解释了如何在 Web 客户端中获取 JSON/String 格式的正文。

【讨论】:

    【解决方案2】:

    您可以通过对请求和响应的小操作来跟踪请求和响应负载:

    public class TracingExchangeFilterFunction implements ExchangeFilterFunction {
     
     
            return next.exchange(buildTraceableRequest(request))
                    .flatMap(response ->
                            response.body(BodyExtractors.toDataBuffers())
                                    .next()
                                    .doOnNext(dataBuffer -> traceResponse(response, dataBuffer))
                                    .thenReturn(response)) ;
        }
    
        private ClientRequest buildTraceableRequest( 
                final ClientRequest clientRequest) {
            return ClientRequest.from(clientRequest).body(
                    new BodyInserter<>() {
                        @Override
                        public Mono<Void> insert(
                                final ClientHttpRequest outputMessage,
                                final Context context) {
                            return clientRequest.body().insert(
                                    new ClientHttpRequestDecorator(outputMessage) {
                                        @Override
                                        public Mono<Void> writeWith(final Publisher<? extends DataBuffer> body) {
                                            return super.writeWith(
                                                    from(body).doOnNext(buffer ->
                                                            traceRequest(clientRequest, buffer)));
                                        }
                                    }, context);
                        }
                    }).build();
        }
    
        private void traceRequest(ClientRequest clientRequest, DataBuffer buffer) {
            final ByteBuf byteBuf = NettyDataBufferFactory.toByteBuf(buffer);
            final byte[] bytes = ByteBufUtil.getBytes(byteBuf);
            // do some tracing e.g. new String(bytes)
        }
    
    
        private void traceResponse(ClientResponse response, DataBuffer dataBuffer) {
            final byte[] bytes = new byte[dataBuffer.readableByteCount()];
            dataBuffer.read(bytes);
            // do some tracing e.g. new String(bytes)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-05-21
      • 1970-01-01
      • 2019-02-17
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-10-02
      • 2019-05-17
      • 2017-02-21
      相关资源
      最近更新 更多