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 过滤器获取请求正文的主要内容,如果未能解决你的问题,请参考以下文章
从 ServerHttpRequest / Flux<DataBuffer> 获取请求正文字符串