spring - Spring-webflux 过滤器获取请求正文
问题描述
我需要在过滤器中获取整个请求体并将其转换为字符串。下面是我的代码,但控制台上没有打印任何内容。
@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;
}
}
解决方案
因为您没有订阅,所以控制台上没有打印任何内容decodedRequest
,因为我们知道 Reactive 方面之一:
在您订阅之前什么都不会发生
但是,如果您这样做,您将在控制台上看到打印的正文,但您的代码将不起作用,因为下一个操作员无法读取正文,您将获得IllegalStateException
(仅允许一个连接接收订阅者。)
那么,如何解决呢?
- 创建您自己的包装器
ServerWebExchange
(请在此处阅读:如何在 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;
}
推荐阅读
- c# - HandleChallengeAsync 返回自定义对象
- visual-studio-code - VSCode 不会将多余的空格突出显示为错误
- python - NameError:名称'random'未在python中定义错误
- image - 如何找到(找出)图像的像素化部分
- javascript - 按键组合
- zend-framework3 - Zend\Session 无效设置
- python - 如何将请求中的 json 数据转换为 excel 文件?
- python - 1 位图像创建 PIL.Image fromarray 错误
- spring - SpringBoot Junit5在重命名包含@SpringBootApplication注释的类的包时失败
- mysql - 无法连接到 docker 容器中的 MySQL 数据库