通过spring集成从分页的REST-Services中读取和下载

时间:2016-07-01 10:04:03

标签: java spring rest spring-integration

目前我正在开发一个Spring Integration应用程序,它具有以下场景:

  1. int-http:outbound-gateway从REST-Services读取分页元素列表:about in
  2. 将每个页面内容拆分并存储在稍后由弹簧批处理作业处理的文件夹中。
  3. 我对弹簧集成很新,我不知道是否可以使用`int-http:outbound-gateway'来创建一种循环。阅读所有页面直到最后一页。

    我们正在谈论在2651页中拆分的66254个元素。我正在寻找的是阅读和下载所有页面并收集数据的最佳实践,而不会出现任何内存问题。

    任何建议都将受到赞赏

    由于

2 个答案:

答案 0 :(得分:2)

是的,这有可能,虽然有点棘手。

假设您的REST服务需要page作为请求参数,因此,您希望从页面#1和循环(递增page参数)发出请求,直到服务返回空结果。 / p>

因此,您可能具有REST服务的配置,如:

<int-http:outbound-gateway url="http://service/elements?page={page}">
    <int-http:uri-variable name="page" expression="headers['page']"/>
</int-http:outbound-gateway>

注意<int-http:uri-variable>定义。从一开始,您必须使用<int-http:outbound-gateway>标题作为page向此1发送邮件。

来自此网关的回复您应该发送到<recipient-list-router><publish-subscribe-channel>之类的内容,其中一个订阅者仍然是您的splitter来将项目存储到该文件夹​​中。

另一位订阅者有点聪明。它从<filter>开始检查payload(来自REST调用的结果)是否为空,这意味着我们已完成并且不再需要检索服务上的页面。否则,您使用<header-enricher>来增加并替换page标头,并将结果发送到我们的第一个<int-http:outbound-gateway>

答案 1 :(得分:0)

我使用 Java DSL for Spring Integration 做了类似的事情:

@Bean
IntegrationFlow servicePointIntegrationFlow() {
    return IntegrationFlows.from("servicePointExportChannel")
            .enrichHeaders(headerEnricherSpec -> headerEnricherSpec.header("pageNumber", new AtomicInteger()))
            .channel("singlePageRequestChannel")
            .get();
}
/**
 * Get a single page, and persist the contents of that page to the DB
 * Then, check if there are more pages.
 *   * If yes, request the next page by adding another message to the same channel (but with incremented pageNumber in the message header)
 *   * If no, publish a message to the next channel
 */
@Bean
IntegrationFlow paginatedDataFlow(ServicePointTransformer servicePointTransformer) {
    return IntegrationFlows.from("singlePageRequestChannel")
            .log(INFO, m -> "paginatedDataFlow called with pageNumber: " + m.getHeaders().get("pageNumber"))
            .handle(Http.outboundGateway(m -> myUrl + "&pageNumber={pageNumber}")
                    .uriVariable("pageNumber", m -> m.getHeaders().get("pageNumber", AtomicInteger.class).getAndIncrement())
                    .httpMethod(HttpMethod.GET)
                    .expectedResponseType(MyPage.class)
                    .mappedResponseHeaders(""))
            .routeToRecipients(route -> route
                    .recipientFlow(flow -> flow
                            .transform(MyPage::getServicePoints)
                            .transform(servicePointTransformer)
                            .handle(Jpa.updatingGateway(myEntityManagerFactory),
                                    spec -> spec.transactional(myTransactionManager))
                    .recipientFlow("payload.isNextPageAvailable", f -> f.channel("singlePageRequestChannel"))
                    .recipientFlow("!payload.isNextPageAvailable", f -> f.channel("someOtherChannel")))
            .get();
}

有效负载/页面是 JSON,包含一个顶级字段 nextPageAvailable,可以以其反序列化形式作为 MyPage.isNextPageAvailable() 访问。