如何在 Spring WebFlux Webfilter 中访问请求正文?

Jas*_*ard 5 java spring spring-boot spring-webflux

如何访问 Spring WebFlux 中的请求正文Webfilter

假设您想要构建一个过滤器来记录请求详细信息,包括所有错误的完整请求正文。

WebFilter::filter方法提供了ServerWebExchange,可用于检索ServerHttpRequest具有getBody返回 的方法的Flux<DataBuffer>。考虑这个不起作用的例子:

@Component
@Slf4j
public class ErrorWebFilter implements WebFilter {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

    return
        chain.filter(exchange)
            .thenReturn(exchange.getResponse())
            .map(ServerHttpResponse::getStatusCode)
            .filter(HttpStatus::isError)
            .then(
                exchange.getRequest().getBody()
                    .map(dataBuffer -> dataBuffer.toString(StandardCharsets.UTF_8))
                    .collect(Collectors.joining())
                    .map(Optional::of)
                    .defaultIfEmpty(Optional.empty())
            )
            .doOnNext(requestBody -> {
              log.info("Error response with statusCode='{}' returned for request: {} {} with query params='{}' with body='{}'.",
                  exchange.getResponse().getRawStatusCode(),
                  exchange.getRequest().getMethod(),
                  exchange.getRequest().getPath(),
                  exchange.getRequest().getQueryParams(),
                  requestBody.orElse("")
              );
            })
            .then();

  }

}
Run Code Online (Sandbox Code Playgroud)

在我们所有的测试中,上述方法不起作用,因为ServerHttpRequest::getBody返回一个Mono.empty(). 即便如此,我仍然怀疑这DataBuffer::toString是否会奏效。

我们如何访问 a 中的响应主体WebFilter

作为参考,我们使用 SpringBoot v2.2.6,其中包括 Spring Framework v5.2.5。