如何在Spring Webflux Java中记录请求正文 [英] How to log request body in spring Webflux Java

查看:123
本文介绍了如何在Spring Webflux Java中记录请求正文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 POST 请求中接收到一些 XML 负载,并希望看到接收到的负载以进行调试.

I am receiving some XML payload in a POST request and want to see the payload as received for debugging purposes.

下面(我的自定义 WebFilter)代码按预期记录了 URI 和请求标头,但没有记录请求正文/有效负载,我的反应式代码一定有问题 -

Below (my custom WebFilter) code logs the URI and request headers as expected but not the request body/payload, must be something wrong with my reactive code -

       final ServerHttpRequest request = exchange.getRequest();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        LOGGER.info("Request: uri={}", request.getURI());
        LOGGER.info("Request: headers={}", request.getHeaders().entrySet());
        request.getBody().doOnNext(dataBuffer -> {
            try {
                Channels.newChannel(baos).write(dataBuffer.asByteBuffer().asReadOnlyBuffer());
                String body = new String(baos.toByteArray());
                LOGGER.info("Request: payload={}", body);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

我查看了布赖恩对下面帖子的回复并遵循了它,但由于没有代码,我可能犯了一些愚蠢的错误

I have looked at Brian's response for post below and followed it but since there is no code, I am probably making some silly mistake

如何在 Spring 中记录请求和响应主体WebFlux

更新代码

@Configuration
public class RequestFilter implements WebFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(RequestFilter.class);

    @Override
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public Mono<Void> filter(ServerWebExchange serverWebExchange,
                             WebFilterChain webFilterChain) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        serverWebExchange.getRequest().getBody().doOnNext(dataBuffer -> {
            try {
                Channels.newChannel(baos).write(dataBuffer.asByteBuffer().asReadOnlyBuffer());
                String body = new String(baos.toByteArray());
                LOGGER.info("Request: payload={}", body);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        return webFilterChain.filter(serverWebExchange);
    }
}

推荐答案

除了在错误的位置提取主体之外,您的做法部分正确.您必须在 ServerHttpRequestDecorator 实现中执行此操作并将其插入 WebFilter 实现中.

You are doing it partially right except that you are extracting the body at the wrong place. You will have to do it in a ServerHttpRequestDecorator implementation and plug it in the WebFilter implementation.

public class RequestLoggingDecorator extends ServerHttpRequestDecorator {

  private static final Logger LOGGER = LoggerFactory.getLogger(RequestLoggingDecorator.class);

  public RequestLoggingDecorator(ServerHttpRequest delegate) {
    super(delegate);
  }

  @Override
  public Flux<DataBuffer> getBody() {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    return super.getBody().doOnNext(dataBuffer -> {
      try {
        Channels.newChannel(baos).write(dataBuffer.asByteBuffer().asReadOnlyBuffer());
        String body = new String(baos.toByteArray(), StandardCharsets.UTF_8);
        LOGGER.info("Request: payload={}", body);
      } catch (IOException e) {
        e.printStackTrace();
      } finally {
        try {
          baos.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    });
  }
}

然后您可以在 WebFilter 实现中进行如下配置:

Then you can configure this in a WebFilter implementation as follows:

@Configuration
public class RequestLoggingFilter implements WebFilter {
  @Override
  public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
    ServerWebExchangeDecorator decorator =
        new ServerWebExchangeDecorator(serverWebExchange) {
          @Override
          public ServerHttpRequest getRequest() {
            return new RequestLoggingDecorator(serverWebExchange.getRequest());
          }
        };

    return webFilterChain.filter(decorator);
  }
}

这应该在每个传入的 Http 请求上记录您的请求正文.

This should log your request body on every incoming Http request.

这篇关于如何在Spring Webflux Java中记录请求正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆