How to log request body in spring Webflux Java

不想你离开。 提交于 2020-06-17 09:32:07

问题


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

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

How to log request and response bodies in Spring WebFlux

Updated Code

@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);
    }
}

回答1:


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();
        }
      }
    });
  }
}

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);
  }
}

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



来源:https://stackoverflow.com/questions/61706948/how-to-log-request-body-in-spring-webflux-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!