使用 Spring WebClient 发出多个请求
Making multiple requests with Spring WebClient
所以我的目标是使用 WebClient 发出多个并发请求,等待它们全部完成,然后合并结果。这是我目前所拥有的:
...
Flux<ServerResponse> feedResponses = request
.bodyToMono(AddFeedRequestDto.class)
.map(AddFeedRequestDto::getFeeds) // Returns a list of RSS feed URLs
.map(this::getServerResponsesFromUrls) // Returns a list of Mono<Feed>
.map(Flux::merge) // Wait til all requests are completed
// Not sure where to go from here
...
/** Related methods: **/
private List<Mono<Feed>> getServerResponsesFromUrls(List<String> feedUrls) {
List<Mono<Feed>> feedResponses = new ArrayList<>();
feedUrls.forEach(feedUrl -> feedResponses.add(getFeedResponse(feedUrl)));
return feedResponses;
}
public Mono<Feed> getFeedResponse(final String url) {
return webClient
.get()
.uri(url)
.retrieve()
.bodyToMono(String.class) // Ideally, we should be able to use bodyToMono(FeedDto.class)
.map(this::convertResponseToFeedDto)
.map(feedMapper::convertFeedDtoToFeed);
}
/** Feed.java **/
@Getter
@Setter
public class Feed {
List<Item> items;
}
基本上我的目标是将每个提要中的所有项目组合起来创建一个统一的提要。但是,我不太确定在调用 Flux::merge 之后要做什么。如有任何建议,我们将不胜感激。
使用.flatMap
代替.map
/Flux.merge
,像这样:
Mono<Feed> unifiedFeedMono = request
.bodyToMono(AddFeedRequestDto.class) // Mono<AddFeedRequestDto>
.map(AddFeedRequestDto::getFeeds) // Mono<List<String>> feedUrls
.flatMapMany(Flux::fromIterable) // Flux<String> feedUrls
.flatMap(this::getFeedResponse) // Flux<Feed>
.map(Feed::getItems) // Flux<List<Item>>
.flatMap(Flux::fromIterable) // Flux<Item>
.collectList() // Mono<List<Item>>
.map(Feed::new); // Mono<Feed>
请注意,.flatMap
是一个异步操作,将并行执行请求。如果你想限制并发,有一个带 concurrency
参数的重载版本。
.flatMap
不能保证顺序,生成的项目可能会交错。如果您想要更多的订购保证,请替换 .concatMap
或 .flatMapSequential
.
所以我的目标是使用 WebClient 发出多个并发请求,等待它们全部完成,然后合并结果。这是我目前所拥有的:
...
Flux<ServerResponse> feedResponses = request
.bodyToMono(AddFeedRequestDto.class)
.map(AddFeedRequestDto::getFeeds) // Returns a list of RSS feed URLs
.map(this::getServerResponsesFromUrls) // Returns a list of Mono<Feed>
.map(Flux::merge) // Wait til all requests are completed
// Not sure where to go from here
...
/** Related methods: **/
private List<Mono<Feed>> getServerResponsesFromUrls(List<String> feedUrls) {
List<Mono<Feed>> feedResponses = new ArrayList<>();
feedUrls.forEach(feedUrl -> feedResponses.add(getFeedResponse(feedUrl)));
return feedResponses;
}
public Mono<Feed> getFeedResponse(final String url) {
return webClient
.get()
.uri(url)
.retrieve()
.bodyToMono(String.class) // Ideally, we should be able to use bodyToMono(FeedDto.class)
.map(this::convertResponseToFeedDto)
.map(feedMapper::convertFeedDtoToFeed);
}
/** Feed.java **/
@Getter
@Setter
public class Feed {
List<Item> items;
}
基本上我的目标是将每个提要中的所有项目组合起来创建一个统一的提要。但是,我不太确定在调用 Flux::merge 之后要做什么。如有任何建议,我们将不胜感激。
使用.flatMap
代替.map
/Flux.merge
,像这样:
Mono<Feed> unifiedFeedMono = request
.bodyToMono(AddFeedRequestDto.class) // Mono<AddFeedRequestDto>
.map(AddFeedRequestDto::getFeeds) // Mono<List<String>> feedUrls
.flatMapMany(Flux::fromIterable) // Flux<String> feedUrls
.flatMap(this::getFeedResponse) // Flux<Feed>
.map(Feed::getItems) // Flux<List<Item>>
.flatMap(Flux::fromIterable) // Flux<Item>
.collectList() // Mono<List<Item>>
.map(Feed::new); // Mono<Feed>
请注意,.flatMap
是一个异步操作,将并行执行请求。如果你想限制并发,有一个带 concurrency
参数的重载版本。
.flatMap
不能保证顺序,生成的项目可能会交错。如果您想要更多的订购保证,请替换 .concatMap
或 .flatMapSequential
.