首页 > 解决方案 > 使用 AbstractPaginatedDataItemReader 进行分页 API 调用的 Spring 批处理

问题描述

我正在尝试调用分页 API,例如。来自 AbstractPaginatedDataItemReader 的搜索 API。我想继续调用这个 API,直到它没有更多的页面数据,我试图在每一页之后继续块,似乎批处理没有超过第 1 页,这是我的代码和配置我正在使用

启动上下文如下

<batch:job id="fileupload">
    <batch:step id="readApi">
        <batch:tasklet>
            <batch:chunk reader="readPaginatedApi" processor="processApiResults"
                         writer="emailItemWriter" commit-interval="10"/>
        </batch:tasklet>
        <batch:next on="NEXT_PAGE" to="readPaginatedApi"/>
        <batch:end on="END" />
    </batch:step>
</batch:job>

这是阅读器片段

@Component("readPaginatedApi")
@Scope("step")
public class ReadPaginatedApi extends AbstractPaginatedDataItemReader<SearchResponse> {

@BeforeStep
public void beforeStep(StepExecution stepExecution) {
    this.setName("READER");
    this.setExecutionContextName("READER");
    
    String pageSizeString = stepExecution.getJobParameters().getString("page_size");
    if (StringUtils.isNotBlank(pageSizeString) && NumberUtils.isParsable(pageSizeString)) {
        try {
            pageSize = Integer.parseInt(pageSizeString);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    String pageString = stepExecution.getJobParameters().getString("page");
    if (StringUtils.isNotBlank(pageString) && NumberUtils.isParsable(pageString)) {
        try {
            page = Integer.parseInt(pageString);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@Override
protected Iterator<Payee> doPageRead() {
    //Call API 
    //Return iterator of results or empty iterator
}

@AfterStep
public ExitStatus afterStep(StepExecution stepExecution) {
    AtomicInteger pageAtomicInteger = new AtomicInteger(page);
    SearchResponse searchResponse = //call service, get response
    if (searchResponse != null && CollectionUtils.isNotEmpty(searchResponse.getItems())) {
        pageAtomicInteger.set(page + 1);
        return new ExitStatus("NEXT_PAGE", String.format("page %d", page));
    }
    return new ExitStatus("END", String.format("page %d", page));
}

}

我在这里想念什么?我怎样才能使这项工作?对于这种情况,这是正确的方法吗?感谢对此的任何帮助

标签: javaspringpaginationspring-batchbatch-processing

解决方案


batch:next, batch:end, 等用于定义作业步骤的执行流程。这些并不打算遍历分页项目阅读器的所有页面,它们用于更高级别。

您需要做的是扩展AbstractPaginatedDataItemReader和实施doPageRead. 您的实现应该维护当前正在读取哪个页面的状态、项目列表等。


推荐阅读