Spring Integration Java DSL: как зациклить постраничный сервис Rest? - PullRequest
0 голосов
/ 09 октября 2018

Как зациклить выгружаемую службу Rest с помощью метода Java DSL Http.outboundGateway?

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 голосов
/ 09 октября 2018

Самый простой способ сделать это, это обернуть вызов этого 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 и этот тип свойству expectedResponseType(PersonPageResult.class) свойства Http.outboundGateway().RestTemplate вместе с MappingJackson2HttpMessageConverter из коробки позволят вам вернуть такой объект в качестве ответа для последующей обработки.

Затем, как я уже говорил, циклбыло бы лучше сделать из некоторого 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) JavaDocs.

Такой 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...