gpt4 book ai didi

java - 使用递增的查询参数重复 WebClient 调用

转载 作者:行者123 更新时间:2023-12-02 01:24:38 25 4
gpt4 key购买 nike

我正在尝试构建一种方法,当一个查询参数小于 45000 时,该方法应该向一个外部端点执行许多 HTTP 请求。

我需要这样做,因为外部端点允许我获取 100 个项目,但要获取的项目超过 44000 个。

private int offset = 0;

public Flux<List<Model>> getItems() {
return Flux.from(
webClientBuilder
.build()
.get()
.uri(uriBuilder -> uriBuilder
.path("/getItems")
.queryParam("limit", 100)
.queryParam("offset", getOffset())
.build())
.retrieve()
.bodyToMono(Model.class)
.doOnSuccess(System.out::println)
.flatMap(model -> {
setOffset(getOffset() + 100);
log.info("Offset: " + getOffset());
return repository.saveAll(model.getData().getResults()).collectList();
}).delayElement(Duration.ofSeconds(15)))
.repeat(() -> getOffset() <= 45000);
}

public int getOffset() {
return offset;
}

public void setOffset(int offset) {
this.offset = offset;
}

它似乎有效,因为记录偏移参数递增,但 HTTP 请求的偏移量等于 0。该方法返回前 100 个项目,而不是 44566 个项目

最佳答案

问题实际上是,webclient 是在订阅之前急切构建的,并使用初始 offset 值“缓存”。每次调用后,Flux 都会重新订阅,但准备好的带有偏移量的 Web 服务调用仍保持“缓存”。您必须以惰性方式提供weblient(例如将其包装在 lambda 中),这会强制为每次调用重新计算其所有参数。有一个特殊的运算符 - defer()

解决方案:

Mono<Model> response = Mono.defer(() -> webClientBuilder
.build()
.get()
.uri(uriBuilder -> uriBuilder
.path("/getItems")
.queryParam("limit", 100)
.queryParam("offset", getOffset())
.build())
.retrieve()
.bodyToMono(Model.class)
);


Flux.from(response
.doOnEach(System.out::println)
.flatMap(model -> {
setOffset(getOffset() + 100);
log.info("Offset: " + getOffset());
return repository.saveAll(model.getData().getResults()).collectList();
}).delayElement(Duration.ofSeconds(15))
).repeat(() -> getOffset() <= 45000).subscribe();

另一个问题演示了急切执行的相同问题: Mono switchIfEmpty() is always called

关于java - 使用递增的查询参数重复 WebClient 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57124648/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com