使用 Spring WebClient 重复过滤响应

Repeatedly filter a response using Spring WebClient

我是 Spring 的新手,甚至是 WebClient 的新手。我想使用 Springs 的 WebClient 以一秒的间隔重复过滤 Get 响应的主体,持续 2 分钟。我正在执行一个获取请求,其中 return 是一个空的 JSON 字符串列表。在某个时刻,正文将被填充,我想 return 这个字符串列表。我想以这种方式过滤响应,当它为空时它继续执行请求直到它被填充并且 return 期望的结果。

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

有人知道怎么做吗?任何帮助将不胜感激。

您可以使用 bodyToFlux 而不是使用 bodyToMono,然后使用 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)...

然后您可以将过滤器逻辑链接到此

我的诀窍是在列表为空时使用 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();