Неоднократно фильтруйте ответ с помощью Spring WebClient - PullRequest
2 голосов
/ 04 августа 2020

Я новичок в Spring и даже новичок в WebClient. Я хочу отфильтровать тело ответа Get несколько раз с интервалом в одну секунду в течение 2 минут с помощью Springs WebClient. Я выполняю запрос на получение, который возвращает пустой список JSON строк. В какой-то момент тело будет заполнено, и я хочу вернуть этот список строк. Я хочу отфильтровать ответ таким образом, чтобы, когда он пуст, он продолжал выполнять запрос до тех пор, пока он не будет заполнен и не вернет желаемый результат.

 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;
    }

Кто-нибудь знает, как это сделать? Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 11 августа 2020

В чем трюк для меня, так это использование flatMap для генерации исключения, когда список пуст, а затем вызова retryWhen, пока список не будет заполнен. (blockOptional удален, потому что больше не нужен)

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();
0 голосов
/ 04 августа 2020

Вместо bodyToMono вы можете использовать bodyToFlux, а затем использовать метод interval. Вы можете разделить запрос следующим образом:

Flux<Account[]> request = webClient.get()
                .uri("example.com")
                .accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToFlux(Account[].class);

, а затем вызывать с интервалом, используя

Flux.interval(Duration.ofSeconds(1), Duration.ofMinutes(2))
  .map(i -> request)...

, затем вы можете связать свой logi фильтра c с этим

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...