StaxEventItemReader - 跳过先前作业执行中处理的XML片段

时间:2015-01-23 10:16:00

标签: spring spring-batch

使用CSV文件并重新启动FAILED作业时,可以使用StepExecutionListner和相关的beforeStep(....)方法来定位 文件中的读者。因此代码看起来像:

public void beforeStep(StepExecution stepExecution) {

    ExecutionContext executionContext = stepExecution.getExecutionContext();

    if (executionContext.containsKey(getKey(LINES_READ_COUNT))) {

        long lineCount = executionContext.getLong(getKey(LINES_READ_COUNT));

        LineReader reader = getReader();
        Object record = "";
        while (reader.getPosition() < lineCount && record != null) {
            record = readLine();
        }
    }
} // Or something similar

我的问题是你在使用StaxEventItemReader时如何实现同样的目标?

我的batch_step_execution_context看起来像{"string":"StaxEventItemReader.read.count","int":6}。所以在我的情况下 成功处理了前5个XML片段,重新启动作业后,我想从第6号XML片段开始处理。

鉴于下面的配置,我如何将阅读器放在XML文件中?

<batch:job id="reportJob" restartable="true">
    <batch:step id="step1">
        <batch:tasklet>
            <batch:chunk reader="xmlItemReader" writer="cvsFileItemWriter" processor="filterReportProcessor"
                commit-interval="1">
            </batch:chunk>
            <batch:listeners>
                <batch:listener ref="step1Listener" />
            </batch:listeners>
        </batch:tasklet>
    </batch:step>
</batch:job>

<bean id="step1Listener" class="com.mkyong.listeners.Step1Listener" />

<bean id="filterReportProcessor" class="com.mkyong.processor.FilterReportProcessor" />

<bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
    <property name="fragmentRootElementName" value="record" />
    <property name="resource" value="classpath:xml/report.xml" />
    <property name="unmarshaller" ref="reportUnmarshaller" />
</bean>

<!-- Read and map values to object, via jaxb2 -->
<bean id="reportUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
        <list>
            <value>com.mkyong.model.Report</value>
        </list>
    </property>
</bean>

环境 - spring-batch-core-2.2.0;弹簧芯3.2.2

测试输入文件

将XML文件转换为CSV文件。

<company>
    <record refId="1001">
        <name>mkyong</name>
        <age>31</age>
        <dob>31/8/1982</dob>
        <income>200,000</income>
    </record>
    <record refId="1002">
        <name>kkwong</name>
        <age>30</age>
        <dob>26/7/1983</dob>
        <income>100,999</income>
    </record>
    <record refId="1003">
        <name>joel</name>
        <age>29</age>
        <dob>21/8/1984</dob>
        <income>1,000,000</income>
    </record>
    <record refId="1004">
        <name>leeyy</name>
        <age>29</age>
        <dob>21/3/1984</dob>
        <income>80,000.89</income>
    </record>
    <record refId="1005">
        <name>Grant</name>
        <age>29</age>
        <dob>21/3/1984</dob>
        <income>80,000.89</income>
    </record>
</company>

测试运行1

在处理输入文件中的两条记录后,我强制使用RunTimeException。

batch_job_execution --->>  "FAILED";"FAILED";"java.lang.RuntimeException: Get me out of here!

batch_step_execution_context --->> {"string":"StaxEventItemReader.read.count","int":2}

Output CSV file --->> 1001,mkyong,31,31/08/1982,200000
                      1002,kkwong,30,26/07/1983,100999

测试运行2

处理所有“剩余数据”,所以期待.... refId =“1003”,refId =“1004”,refId =“1005”

batch_job_execution --->>  "COMPLETED";"COMPLETED";"''";"2015-01-25 16:18:08.587"

batch_step_execution_context --->>  {"string":"StaxEventItemReader.read.count","int":6}


Output CSV file --->> 1001,mkyong,31,31/08/1982,200000
                      1002,kkwong,30,26/07/1983,100999
                      1003,joel,29,21/08/1984,1000000
                      1004,leeyy,29,21/03/1984,80000.89
                      1005,Grant,29,21/03/1984,80000.89

测试结果

不幸的是,看起来StaxEventItemReader正在从文件的开头读取,而不是根据第一次测试后设置为2的StaxEventItemReader.read.count的值重新定位自己。

1 个答案:

答案 0 :(得分:1)

您不需要配置任何内容,这已经是StaxEventItemReader的默认行为。当它打开时,它会从步骤执行上下文中的读取计数重新定位。