When applying webfilter, I found that it cannot handle Mono.empty() returned from controllers The below codes (switchIfEmpty) make empty messages return to Mono.empty() directly
## https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java
if (inputStream instanceof Mono) {
return body
.singleOrEmpty()
.switchIfEmpty(Mono.defer(() -> {
message.getHeaders().setContentLength(0);
return message.setComplete().then(Mono.empty());
}))
.flatMap(buffer -> {
Hints.touchDataBuffer(buffer, hints, logger);
message.getHeaders().setContentLength(buffer.readableByteCount());
return message.writeWith(Mono.just(buffer)
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release));
})
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
}
As you know, webfilter can wrap or rewrite the message when controller returns body with data. In case of empty, a developer cannot wrap additional data through webfilter even if it is an empty because empty message is returned directly.
So, I think it would be better to create new function to handle message or to reuse writeWith regardless of value received from controller
Comment From: rstoyanchev
Result handling, including writing the response body (empty or not) happens within DispatcherHandler
and a WebFilter
on the outbound side is after that. So I don't expect there should be any difference whether the controller returned Mono.empty() or some actual data.
Comment From: liuzhongkai
The controller returns empty, you can add a default callback
Comment From: rstoyanchev
A WebFilter cannot change the response regardless of what the controller returns. This is expected behavior. I understand what you want to do but it's not possible nor supported currently in a cross-cutting way.
The controller returns empty, you can add a default callback
Add a callback to what?
Comment From: timewizhan
Thanks for the reply.
Um... I currently applied WebFilter to change the response with WebServerExchange. For example, when ServerHttpResponse is manipulated in WebFilter#filter, the databuffer for the response is overwritten by the "writeWith" function. In case that the controller has a body, the below codes is executed
message.writeWith(Mono.just(buffer)
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release));
Perhaps, is it to misuse the webfilter??
Otherwise, I think it would be better a chance to overwrap returned data than to bypass Mono.empty directly
Comment From: rstoyanchev
The body cannot be set twice and I'm not sure what exactly your WebFilter does. Can you show some example code?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.