Environment: - Spring Boot 3.0 - Spring Framework 6.0 - Reactor Core 3.5
Hello, when migrating from Spring Boot 2.7 to Spring 3.0 I encountered a problem with reading full request body for logging or another operation. Before I was able to use Mono.subscriberContext() but now I have to use Mono.deferContextual(), does anyone know how to migrate such code to retain it with context? It is needed for implementing ServerHttpRequestDecorator, where delegate is ServerHttpRequest:
override fun getBody(): Flux<DataBuffer> = DataBufferUtils.join(super.getBody())
.zipWith(Mono.subscriberContext())
.flatMapMany { fullBodyWithSubscriberContext ->
val fullBody = fullBodyWithSubscriberContext.t1
DataBufferUtils.retain(fullBody)
// Custom action with body
logger.info(delegate, fullBody.getBytes())
Flux.just(fullBody).doAfterTerminate {
DataBufferUtils.release(
fullBody
)
}
}
Without such operation when we just extract bytes we will get only like 1700 bytes for the first operation so we are unable to log everything in one entry:
override fun getBody(): Flux<DataBuffer> = delegate.body.doOnNext {
logger.info(delegate, extractBytes(it))
}
private fun extractBytes(data: DataBuffer): ByteArray {
val bytes = ByteArray(data.readableByteCount())
data.read(bytes)
data.readPosition(0)
return bytes
}
Above examples were found on the web but now changes need to be made to work properly with the new version. Any suggestions will be appreciated.
Comment From: simonbasle
Zipping with Mono.subscriberContext
and then accessing the sides of the resulting Tuple
is no longer needed once you wrap everything up in Mono.deferContextual
. The key is to create the DataBuffer Mono
inside the deferred block, and applying the flatMapMany
there as well.
(I assume your example is simplified because it doesn't make any use of the Context
)
someMono.zipWith(Mono.subscriberContext())
.flatMapMany(bodyContextTuple -> {
Object body = bodyContextTuple.getT1();
Context ctx = bodyContextTuple.getT2();
//...for example:
return Flux.just(body, ctx);
});
becomes:
Mono.deferContextual(ctx ->
someMono.flatMapMany(body -> Flux.just(body, ctx))
);
If you have any further questions, please follow up on Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
(marking as for: stackoverflow
&status: invalid
as a result)