Spring-webflux过滤器来获取请求体

问题描述 投票:0回答:1

我需要在过滤器中获取整个请求体并将其转换为String。下面是我的代码,但没有任何东西在控制台上打印。

@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;
    }
}
spring filter nonblocking spring-webflux reactive
1个回答
1
投票

由于您没有订阅decodedRequest,因此我们知道其中一个Reactive方面,因此无法在控制台上打印任何内容:

在您订阅之前没有任何事情发生

但是,如果你这样做,你会在控制台上看到印刷体,但你的代码将无法工作,因为下一个操作员无法读取正文,你将获得IllegalStateException(只允许一个连接接收用户。)

那么,如何解决呢?

  1. ServerWebExchange创建自己的包装器(请在此处阅读:How to log request and response bodies in 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; }
© www.soinside.com 2019 - 2024. All rights reserved.