Как получить доступ к телу запроса в 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();
}
}
Во всех наших тестах вышеприведенное не работает, потому что ServerHttpRequest::getBody
возвращает Mono.empty()
. И даже тогда я сомневаюсь, что DataBuffer::toString
сработает.
Как получить доступ к телу ответа в WebFilter
?
Для справки мы используем SpringBoot v2.2.6, который включает Spring Framework v5.2.5.