Spring 集成 Java DSL:如何循环分页 Rest 服务?
Spring Integration Java DSL: How to loop the paged Rest service?
如何使用 Java DSL Http.outboundGateway
方法循环分页 Rest 服务?
其余URL例如
http://localhost:8080/people?page=3
例如 returns
"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))
访问一个页面,如何循环所有页面?
最简单的方法就是用 @MessagingGateway
包装对 Http.outboundGateway()
的调用,并提供页码作为参数:
@MessagingGateway
public interface HttpPagingGateway {
@Gateway(requestChannel = "httpPagingGatewayChannel")
String getPage(int page);
}
然后你得到一个 JSON 作为结果,你可以将它转换成一些域模型或者只执行一个 JsonPathUtils.evaluate()
(基于 json-path)来获得的值last
属性以确保您需要为 page++
调用 getPage()
。
page
参数将成为要发送的消息的 payload
,可以用作 uriVariable
:
.handle(Http
.outboundGateway("http://localhost:8080/people?page={page}")
.httpMethod(HttpMethod.GET)
.uriVariable("page", Message::getPayload)
.expectedResponseType(String.class))
当然,我们可以做类似Spring集成的事情,但是会涉及到filter
、router
等一些组件。
更新
首先,我建议您创建一个域模型(一些 Java Bean),比方说 PersonPageResult
,以表示 JSON 响应和此类型到 expectedResponseType(PersonPageResult.class)
属性 的 Http.outboundGateway()
。 RestTemplate
和开箱即用的 MappingJackson2HttpMessageConverter
一起可以为您 return 这样的对象作为下游处理的回复。
然后,正如我之前所说,从一些 Java 代码开始循环会更好,您可以将其包装到服务激活器调用中。为此,您应该像这样声明一个网关:
public interface HttpPagingGateway {
PersonPageResult getPage(int page);
}
注意:完全没有注释。这个技巧是通过 IntegrationFlow
:
完成的
@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)
Java文档。
这样的 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
,我建议有单独的 IntegrationFlow
,它也可以从网关开始,或者您可以只发送一个 Message<List<Person>>
到它的输入通道。
这样您将分离分页和处理的关注点,并且在某些 POJO 方法中具有简单的循环逻辑。
如何使用 Java DSL Http.outboundGateway
方法循环分页 Rest 服务?
其余URL例如
http://localhost:8080/people?page=3
例如 returns
"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))
访问一个页面,如何循环所有页面?
最简单的方法就是用 @MessagingGateway
包装对 Http.outboundGateway()
的调用,并提供页码作为参数:
@MessagingGateway
public interface HttpPagingGateway {
@Gateway(requestChannel = "httpPagingGatewayChannel")
String getPage(int page);
}
然后你得到一个 JSON 作为结果,你可以将它转换成一些域模型或者只执行一个 JsonPathUtils.evaluate()
(基于 json-path)来获得的值last
属性以确保您需要为 page++
调用 getPage()
。
page
参数将成为要发送的消息的 payload
,可以用作 uriVariable
:
.handle(Http
.outboundGateway("http://localhost:8080/people?page={page}")
.httpMethod(HttpMethod.GET)
.uriVariable("page", Message::getPayload)
.expectedResponseType(String.class))
当然,我们可以做类似Spring集成的事情,但是会涉及到filter
、router
等一些组件。
更新
首先,我建议您创建一个域模型(一些 Java Bean),比方说 PersonPageResult
,以表示 JSON 响应和此类型到 expectedResponseType(PersonPageResult.class)
属性 的 Http.outboundGateway()
。 RestTemplate
和开箱即用的 MappingJackson2HttpMessageConverter
一起可以为您 return 这样的对象作为下游处理的回复。
然后,正如我之前所说,从一些 Java 代码开始循环会更好,您可以将其包装到服务激活器调用中。为此,您应该像这样声明一个网关:
public interface HttpPagingGateway {
PersonPageResult getPage(int page);
}
注意:完全没有注释。这个技巧是通过 IntegrationFlow
:
@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)
Java文档。
这样的 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
,我建议有单独的 IntegrationFlow
,它也可以从网关开始,或者您可以只发送一个 Message<List<Person>>
到它的输入通道。
这样您将分离分页和处理的关注点,并且在某些 POJO 方法中具有简单的循环逻辑。