Repeatedly filter a response using Spring WebClient

Tags: , , , ,



I’m new to Spring and even newer to WebClient. I want to filter the body of a Get response repeatedly with one second intervals for 2 minute duration using Springs’ WebClient. I’m performing a get request which returns an empty JSON list of strings. At some moment of time the body is going to be populated and I want to return this list of strings. I want to filter the response in such way, that when it is empty it continues to perform the request until it is populated and return the desired result.

 private List<String> checkUser() {
        List<String> ibanList = new ArrayList<>();

        ExchangeFilterFunction filter = ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
            if (clientResponse.body())
                  //something here

        });

        Optional<Account[]> accountsOptional = webClient.get()
                .uri("example.com")
                .accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToMono(Account[].class)
                .delaySubscription(Duration.ofSeconds(1))
                .retry()
                .filter(filter)
                .blockOptional(Duration.ofMinutes(2));

        if (accountsOptional.isPresent()) {

            for (Account account : accountsOptional.get()) {
                ibanList.add(account.getIban());
            }
            return ibanList;
        }
        return null;
    }

Does anybody have an idea how to do this? Any help would be appreciated.

Answer

What did the trick for me was using flatMap to throw exception when the list is empty and then calling retryWhen, until the list is populated. (blockOptional removed, because not needed anymore)

Account[] accounts = webClient.get()
                    .uri("example.com")
                    .accept(MediaType.APPLICATION_JSON)
                    .retrieve()
                    .bodyToMono(Account[].class)
                    .delaySubscription(Duration.ofSeconds(1))
                    .flatMap(resp -> {
                        if (resp.length == 0) {
                            return Mono.error(Exception::new);
                        } else {
                            return Mono.just(resp);
                        }
                    })
                    .retryWhen(Retry.max(60))
                    .block();


Source: stackoverflow