目前我正在开发一个Spring Integration应用程序,它具有以下场景:
int-http:outbound-gateway
从REST-Services读取分页元素列表:about in 我对弹簧集成很新,我不知道是否可以使用`int-http:outbound-gateway'来创建一种循环。阅读所有页面直到最后一页。
我们正在谈论在2651页中拆分的66254个元素。我正在寻找的是阅读和下载所有页面并收集数据的最佳实践,而不会出现任何内存问题。
任何建议都将受到赞赏
由于
答案 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()
访问。