当前位置: 首页 > 知识库问答 >
问题:

如何使用Spring bootWebClient收集分页API响应?

缪朝
2023-03-14

我有一个来自URL的分页响应,我想继续点击我从上一个响应中获得的下一页URL,并继续收集项目,直到我的响应中没有“nextPage”URL。如何使用WebFlux的Spring引导WebClient在没有阻塞的情况下以反应式方式实现这一点?

Request1: 

    GET /items
    response: 
    {
        items: [...]
        nextPage: "/items?page=2"
    }


    Request2: 

    GET /items?page=2
    response: 
    {
        items: [...]
        nextPage: "/items?page=3"
    }


    Request3: 

    GET /items?page=3
    response: 
    {
        items: [...]
        nextPage: null
    }

在这里,我创建了模拟网址https://karthikdivi.com/apps/paginatedReviews/withNextPageTokens/itemshttps://karthikdivi.com/apps/paginatedReviews/withNextPageTokens/items?page=2https://karthikdivi.com/apps/paginatedReviews/withNextPageTokens/items?page=3

如何在不阻塞的情况下,以被动方式从上述响应中提取所有项目?

共有2个答案

姜智渊
2023-03-14

您可以使用扩展来达到预期的效果:

@Test
public void usingExpand(){

    Request innerData = new Request(null);
    Request middleData = new Request(innerData);
    Request rootData = new Request(middleData);

    Mono.just(rootData)
            .expand( t -> Mono.justOrEmpty(t.nextPage))
            .flatMap( t -> Flux.fromIterable(t.items))
            .subscribe(System.out::println);

}

public static class Request {
    List<String> items = new ArrayList<>();
    Request nextPage;

    public Request(Request nextPage) {
        this.items.add(UUID.randomUUID().toString());
        this.items.add(UUID.randomUUID().toString());
        this.nextPage = nextPage;
    }
}

上述代码应产生以下结果:

dc78317c-5552-4723-90db-5392c67655be
32ff12bb-5be1-415e-b481-dab85d9157dd
cf1e3f36-a8e2-414d-90a2-7708eeedc5be
91a6bc14-a396-483d-a66a-80bb98dc1968
c95adae3-8e6f-489b-8a9d-4cea3080e150
d6f8fe01-2c50-4574-958c-ec675331bb25

每个数据对象有两个UUID。

张砚
2023-03-14

使用expand可以实现这一点。基于您提供的模拟URL。

public Mono<List<Item>> getItems() {
    String url = "https://karthikdivi.com/apps/paginatedReviews/withNextPageTokens/items";

    return fetchItems(url).expand(response -> {
        if (response.getNextPage() == null) {
            return Mono.empty();
        }
        return fetchItems(response.getNextPage());
    }).flatMap(response -> Flux.fromIterable(response.getItems())).collectList();
}

private Mono<Response> fetchItems(String url) {

         return client.get().uri(url).retrieve()
                    .bodyToMono(Response.class);
    }
 类似资料:
  • 在服务器端,我正在使用一个HTTP API,它以页面形式返回结果。如中所示,响应包含x个结果,如果有超过0的结果,我可以再次调用它以获得下一个x个结果。x可以任意选择直到API的最大页面大小。 现在,我想要在WebSocket上高效地流式传输全套结果,而不会使它不堪重负(施加背压)。最初,我构建了整个resultset,然后从中创建了一个源代码: 这样可以工作,WebSocket客户机以其最大速度

  • 问题内容: 我正在编写的API大约有2000条记录,通过我编写的简单RESTful API以JSON返回。 为了减少大量数据的问题,我想使用分页,以便仅通过诸如or 或等返回每个请求的前10个或前20个。 但是我的问题是,iOS如何知道何时获得下一页结果? 我真的不确定如何执行此操作。用户可能正在快速滚动,因此API可能没有足够的时间一次检索20或50条记录。 与此相关的另一个问题是,假设用户在U

  • 问题内容: 假设我有一个Post实体和一个Comment实体,以及一对多关系: 我如何实现这样的分页: 是否可以在JPA上使用@OneToMany集合来模拟动态分页,还是必须完全重写JPA的关联机制?(例如,创建一个PersistentList集合类型,该类型可以管理分页,排序和搜索)。 PS:我最近找到了Play!框架在JPA上使用了一个非常有趣的库:Siena。Siena非常易于使用,并且是J

  • 我必须使用REST API获取数据并在Angular 2表中使用它。 所以我想知道哪一个是最好的解决方案: > 在API端处理分页、排序和过滤。因此API将只返回要显示在当前页面中的数据。使用此方法将需要多次调用API,因为每个操作都会引发API调用。 API返回所有数据,分页/筛选/排序将使用Angular 2进行管理。

  • 我有一个问题,希望有人能帮助我提高Java流API的知识。 我的服务通过RabbitMQ以如下数组的形式从另一个服务接收数据: 我需要对这些数据做的是将其收集到用户具有userId的列表和设备id的列表中。因此,从上面的数据来看,它应该是: 我确实有一个可行的解决方案,但它很笨拙 解决方案是: 如何对流执行相同的操作?谢谢

  • 我是mongoDb中的一个noob,我需要为任何特定的集合实现分页,例如,比方说 我有一个集合Foo,我有一个函数从Foo集合返回所有记录 但是我需要通过实现分页从Foo获取记录,我如何使用mongoTemplate Spring data MongoDB来实现这一点呢?