如何使用Java DSL Http.outboundGateway
方法循环分页的Rest服务?
例如,其余URL
http://localhost:8080/people?page=3
并返回例如
"content": [
{"name": "Mike",
"city": "MyCity"
},
{"name": "Peter",
"city": "MyCity"
},
...
]
"pageable": {
"sort": {
"sorted": false,
"unsorted": true
},
"pageSize": 20,
"pageNumber": 3,
"offset": 60,
"paged": true,
"unpaged": false
},
"last": false,
"totalElements": 250,
"totalPages": 13,
"first": false,
"sort": {
"sorted": false,
"unsorted": true
},
"number": 3,
"numberOfElements": 20,
"size": 20
}
其中变量totalPages
表示总页数。
所以如果实施
integrationFlowBuilder
.handle(Http
.outboundGateway("http://localhost:8080/people?page=3")
.httpMethod(HttpMethod.GET)
.expectedResponseType(String.class))
访问一页,如何循环浏览所有页面?
答案 0 :(得分:1)
最简单的方法是将调用Http.outboundGateway()
包装到@MessagingGateway
并提供页码作为参数:
@MessagingGateway
public interface HttpPagingGateway {
@Gateway(requestChannel = "httpPagingGatewayChannel")
String getPage(int page);
}
然后,您将得到一个JSON,您可以在其中将其转换为某些域模型,或者仅执行JsonPathUtils.evaluate()
(基于json-path)以获取last
的值属性,以确保您需要为getPage()
调用page++
。
page
参数将成为要发送的消息的payload
,并且可以用作uriVariable
:
.handle(Http
.outboundGateway("http://localhost:8080/people?page={page}")
.httpMethod(HttpMethod.GET)
.uriVariable("page", Message::getPayload)
.expectedResponseType(String.class))
当然,我们可以使用Spring Integration做类似的事情,但是将涉及filter
,router
和其他一些组件。
更新
首先,我建议您创建一个域模型(例如Java Bean),例如PersonPageResult
,以表示该JSON响应以及此类型的{{1 }}。 expectedResponseType(PersonPageResult.class)
与现成的Http.outboundGateway()
一起将为您提供技巧,让您返回这样的对象作为对下游处理的答复。
然后,就像我之前说的那样,最好使用一些Java代码进行循环,您可以将其包装到服务激活器调用中。为此,您应该声明一个这样的网关:
RestTemplate
请注意:完全没有注释。诀窍是通过MappingJackson2HttpMessageConverter
完成的:
public interface HttpPagingGateway {
PersonPageResult getPage(int page);
}
请参阅IntegrationFlow
JavaDocs。
可以使用硬循环逻辑将这样的@Bean
public IntegrationFlow httpGatewayFlow() {
return IntegrationFlows.from(HttpPagingGateway.class)
.handle(Http
.outboundGateway("http://localhost:8080/people?page={page}")
.httpMethod(HttpMethod.GET)
.uriVariable("page", Message::getPayload)
.expectedResponseType(PersonPageResult.class))
}
注入到某些服务中:
IntegrationFlows.from(Class<?> aClass)
对于处理那些HttpPagingGateway
,我建议使用单独的int page = 1;
boolean last = false;
while(!last) {
PersonPageResult result = this.httpPagingGateway.getPage(page++);
last = result.getLast();
List<Person> persons = result.getPersons();
// Process persons
}
,它也可以从网关开始,或者您可以将persons
发送到其输入通道。
通过这种方式,您可以将对分页和处理的关注分开,并且在某些POJO方法中将具有简单的循环逻辑。