使用 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();
我是 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();