Spring Integration Java DSL:如何循环分页的Rest服务?

时间:2018-10-09 07:58:58

标签: spring spring-integration spring-integration-dsl

如何使用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))

访问一页,如何循环浏览所有页面?

1 个答案:

答案 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做类似的事情,但是将涉及filterrouter和其他一些组件。

更新

首先,我建议您创建一个域模型(例如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方法中将具有简单的循环逻辑。