map vs flatMap in reactor

map is for synchronous, non-blocking, 1-to-1 transformations flatMap is for asynchronous (non-blocking) 1-to-N transformations The difference is visible in the method signature: map takes a Function<T, U> and returns a Flux<U> flatMap takes a Function<T, Publisher<V>> and returns a Flux<V> That’s the major hint: you can pass a Function<T, Publisher<V>> to a map, but it … Read more

Mono switchIfEmpty() is always called

It’s because switchIfEmpty accepts Mono “by value”. Meaning that even before you subscribe to your mono, this alternative mono’s evaluation is already triggered. Imagine a method like this: Mono<String> asyncAlternative() { return Mono.fromFuture(CompletableFuture.supplyAsync(() -> { System.out.println(“Hi there”); return “Alternative”; })); } If you define your code like this: Mono<String> result = Mono.just(“Some payload”).switchIfEmpty(asyncAlternative()); It’ll always … Read more

Adding a retry all requests of WebClient

I figured this out, which was apparent after seeing retry only works on exceptions, webClient doesn’t throw the exception, since the clientResponse object just holds the response, only when bodyTo is called is the exception thrown on http status, so to fix this, one can mimic this behaviour @Bean(name = “retryWebClient”) public WebClient retryWebClient(WebClient.Builder builder, … Read more

How to set a timeout in Spring 5 WebFlux WebClient

To set the read and connect timeout I use the method below, because the SO_TIMEOUT option is not available for channels using NIO (and giving the warning Unknown channel option ‘SO_TIMEOUT’ for channel ‘[id: 0xa716fcb2]’) ReactorClientHttpConnector connector = new ReactorClientHttpConnector( options -> options.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000) .compression(true) .afterNettyContextInit(ctx -> { ctx.addHandlerLast(new ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS)); })); return WebClient.builder() .clientConnector(connector) … Read more

How to correctly read Flux and convert it to a single inputStream

This is really not as complicated as other answers imply. The only way to stream the data without buffering it all in memory is to use a pipe, as @jin-kwon suggested. However, it can be done very simply by using Spring’s BodyExtractors and DataBufferUtils utility classes. Example: private InputStream readAsInputStream(String url) throws IOException { PipedOutputStream … Read more

Can I use SpringMvc and webflux together?

As explained in the Spring Boot reference documentation, Spring Boot will auto-configure a Spring MVC application if both MVC and WebFlux are available. There are several reasons for this: Spring MVC can’t run on Netty both infrastructure will compete for the same job (for example, serving static resources, the mappings, etc) mixing both runtime models … Read more

what does Mono.defer() do?

It is a bit of an oversimplification but conceptually Reactor sources are either lazy or eager. More advanced ones, like an HTTP request, are expected to be lazily evaluated. On the other side the most simple ones like Mono.just or Flux.fromIterable are eager. By that, I mean that calling Mono.just(System.currentTimeMillis()) will immediately invoke the currentTimeMillis() … Read more

Spring Boot 2.0 disable default security

According to the new updates in Spring 2.0, if Spring Security is on the classpath, Spring Boot will add @EnableWebSecurity.So adding entries to the application.properties ain’t gonna work (i.e it is no longer customizable that way). For more information visit the official website Security changes in Spring Boot 2.0 Albeit not sure about your requirement … Read more

How to customize SpringWebFlux WebClient JSON deserialization?

Here’s an example that customizes the ObjectMapper for JSON (de)serialization. Note that for streaming purposes, different encoders/decoders are being used but the principle remains the same for their configuration. ExchangeStrategies strategies = ExchangeStrategies .builder() .codecs(clientDefaultCodecsConfigurer -> { clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(new ObjectMapper(), MediaType.APPLICATION_JSON)); clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON)); }).build(); WebClient webClient = WebClient.builder().exchangeStrategies(strategies).build();

block()/blockFirst()/blockLast() are blocking error when calling bodyToMono AFTER exchange()

First, a few things that will help you understand the code snippet solving this use case. You should never call a blocking method within a method that returns a reactive type; you will block one of the few threads of your application and it is very bad for the application Anyway as of Reactor 3.2, … Read more