简体   繁体   中英

Passing Context from one Mono to another - Context is empty

I am trying to pass context from one Mono to another, and access it later, but obviously I do something wrong. Thank you

Mono<String> hello = Mono.just("Empty").subscriberContext(ctx -> ctx.put("message","hellooooo"));
 
Mono<String> world = Mono.subscriberContext().map( ctx -> (String)ctx.get("message"));

world.subscribe(s -> System.out.println("\n Monos content: " + s));

And this is the error I got:

reactor.core.Exceptions$ErrorCallbackNotImplemented: java.util.NoSuchElementException: Context is empty
Caused by: java.util.NoSuchElementException: Context is empty
    at reactor.util.context.Context0.get(Context0.java:42) ~[reactor-core-3.4.14.jar:3.4.14]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Assembly trace from producer [reactor.core.publisher.MonoMapFuseable] :
    reactor.core.publisher.Mono.map(Mono.java:3411)
...

As mentioned in the comments, it is because they are not in the same reactive flow. But then - how the context is passed when I implement my own Filter(implements WebFilter) and return:

return webFilterchain.filter(exchange).subscriberContext(c->c.put("key","value-key"));

After this, the context is visible in any controller, just like this:

Mono<String> parameter= Mono.subscriberContext().map(s->s.get("key")); 

What happened, that context is now visible in my parameter variable? In documentation I can see, that filter method in WebFilterChain does some special delegation of the context "Delegate to the next WebFilter in the chain.". But not sure, what happened that it is visible in my custom "parameter" mono. How context was passed, and can I do something similar also with my custom reactive flows?

As other have stated in comments, in your example you are creating two totally disconnected Mono s. One that writes to its context, and one that reads from (the default, ie. empty) context.

Context is only accessible if the read and write steps are part of a single reactive chain of operators.

Spring WebFlux ensures that this is the case, ie as long as you do delegate in the webFilterChain, Spring ensures that the operators you apply are part of a single chain that ties the request / subscription at the bottom and the Flux or Mono from the @Controller at the top, so you can read context inside the controller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM