Spring-webflux фильтр для получения тела запроса - PullRequest
0 голосов
/ 01 марта 2019

Мне нужно получить все тело запроса в фильтре и преобразовать его в строку.Ниже приведен мой код, но на консоли ничего не печатается.

@Component
public class WebFilter01 implements WebFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange, 
      WebFilterChain webFilterChain) {    

        Flux<DataBuffer> requestBody = serverWebExchange.getRequest().getBody();        

        Flux<String> decodedRequest = requestBody.map(databuffer -> {
            return decodeDataBuffer(databuffer);
        });     
        decodedRequest.doOnNext(s -> System.out.print(s));
        return webFilterChain.filter(serverWebExchange);
    }


    protected String decodeDataBuffer(DataBuffer dataBuffer) {
        Charset charset = StandardCharsets.UTF_8;       
        CharBuffer charBuffer = charset.decode(dataBuffer.asByteBuffer());      
        DataBufferUtils.release(dataBuffer);        
        String value = charBuffer.toString();
        return value;
    }
}

1 Ответ

0 голосов
/ 04 марта 2019

На консоли ничего не печатается, потому что вы не подписались на decodedRequest, так как мы знаем один из аспектов Реактива:

Ничего не происходит, пока вы не подпишетесь

Но если вы сделаете это, вы увидите напечатанное тело на консоли, но ваш код не будет работать, потому что следующие операторы не смогут прочитать тело, и вы получите IllegalStateException ( Разрешено только одно соединение, получающее подписчика. )

Так, как решить это?

  1. Создайте свою собственную обертку для ServerWebExchange (пожалуйста, прочитайте об этом здесь: Как регистрировать тела запросов и ответов в Spring WebFlux )
  2. Регистрировать тела в HttpMessageDecoder.Например, если вы видите AbstractJackson2Decoder, вы найдете код, в котором Spring расшифрует ваш буфер для объекта и может записать его:

    try { Object value = reader.readValue(tokenBuffer.asParser(getObjectMapper())); if (!Hints.isLoggingSuppressed(hints)) { LogFormatUtils.traceDebug(logger, traceOn -> { String formatted = LogFormatUtils.formatValue(value, !traceOn); return Hints.getLogPrefix(hints) + "Decoded [" + formatted + "]"; }); } return value; }

...