Spring-webflux 过滤器获取请求正文

Posted

技术标签:

【中文标题】Spring-webflux 过滤器获取请求正文【英文标题】:Spring-webflux filter to fetch the request body 【发布时间】:2019-07-23 03:11:02 【问题描述】:

我需要在过滤器中获取整个请求体并将其转换为字符串。以下是我的代码,但控制台上没有打印任何内容。

@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】:

由于您没有订阅decodedRequest ,控制台上没有打印任何内容, 正如我们所知道的反应方面之一:

在您订阅之前什么都不会发生

但如果您这样做,您将在控制台上看到打印的正文,但您的代码将不起作用,因为下一个操作员无法读取正文,您将收到 IllegalStateException(仅允许一个连接接收订阅者。强>)

那么,如何解决呢?

    ServerWebExchange 创建自己的包装器(请在此处阅读:How to log request and response bodies in Spring WebFlux) 在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;

【讨论】:

以上是关于Spring-webflux 过滤器获取请求正文的主要内容,如果未能解决你的问题,请参考以下文章

如何在spring-webflux中获取当前请求的上下文

WebClient - 如何获取请求正文?

从 ServerHttpRequest / Flux<DataBuffer> 获取请求正文字符串

如何使用保留请求正文和响应正文的 servlet 过滤器记录请求和响应?

关于 Spring-WebFlux 的一些想法

Java过滤器 - 根据请求有条件地更改响应正文