我需要在过滤器中获取整个请求正文并将其转换为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;
}
}
答案 0 :(得分: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;
}