【问题标题】:Multiple input file Spring Batch多个输入文件 Spring Batch
【发布时间】:2026-02-21 20:05:01
【问题描述】:

我正在尝试开发一个批处理,它可以使用 Spring Batch 处理包含文件的目录。
我查看了 MultiResourcePartitioner 并尝试了类似的东西:

<job parent="loggerParent" id="importContractESTD" xmlns="http://www.springframework.org/schema/batch">
    <step id="multiImportContractESTD">
        <batch:partition step="partitionImportContractESTD" partitioner="partitioner">
            <batch:handler grid-size="5" task-executor="taskExecutor" />
        </batch:partition>
    </step>
</job>

<bean id="partitioner" class="org.springframework.batch.core.partition.support.MultiResourcePartitioner">
    <property name="keyName" value="inputfile" />
    <property name="resources" value="file:${import.contract.filePattern}" />
</bean>

<step id="partitionImportContractESTD" xmlns="http://www.springframework.org/schema/batch">
    <batch:job ref="importOneContractESTD" job-parameters-extractor="defaultJobParametersExtractor" />
</step>

<bean id="defaultJobParametersExtractor" class="org.springframework.batch.core.step.job.DefaultJobParametersExtractor"
    scope="step" />

<!-- Job importContractESTD definition -->
<job parent="loggerParent" id="importOneContractESTD" xmlns="http://www.springframework.org/schema/batch">
    <step parent="baseStep" id="initStep" next="calculateMD5">
        <tasklet ref="initTasklet" />
    </step>
    <step id="calculateMD5" next="importContract">
        <tasklet ref="md5Tasklet">
            <batch:listeners>
                <batch:listener ref="md5Tasklet" />
            </batch:listeners>
        </tasklet>
    </step>
    <step id="importContract">
        <tasklet>
            <chunk reader="contractReader" processor="contractProcessor" writer="contractWriter" commit-interval="${commit.interval}" />
            <batch:listeners>
                <batch:listener ref="contractProcessor" />
            </batch:listeners>
        </tasklet>
    </step>
</job>

<!-- Chunk definition : Contract ItemReader -->
<bean id="contractReader" class="com.sopra.banking.cirbe.acquisition.batch.AcquisitionFileReader" scope="step">
    <property name="resource" value="#{stepExecutionContext[inputfile]}" />
    <property name="lineMapper">
        <bean id="contractLineMappe" class="org.springframework.batch.item.file.mapping.PatternMatchingCompositeLineMapper">
            <property name="tokenizers">
                <map>
                    <entry key="1*" value-ref="headerTokenizer" />
                    <entry key="2*" value-ref="contractTokenizer" />
                </map>
            </property>
            <property name="fieldSetMappers">
                <map>
                    <entry key="1*" value-ref="headerMapper" />
                    <entry key="2*" value-ref="contractMapper" />
                </map>
            </property>
        </bean>
    </property>
</bean>

<!-- MD5 Tasklet -->
<bean id="md5Tasklet" class="com.sopra.banking.cirbe.acquisition.batch.AcquisitionMD5Tasklet">
    <property name="file" value="#{stepExecutionContext[inputfile]}" />
</bean>

但我得到的是:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'stepExecutionContext' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext'

我正在寻找一种方法来为 file:${import.contract.filePattern} 中包含的每个文件启动我的工作 importOneContractESTD。每个文件在步骤 calculateMD5 (将处理后的文件 md5 放入我的 jobContext)和步骤 importContract (从 jobContext 中读取前一个 md5 以添加它作为contractProcessor处理的每一行的数据)

如果我只尝试使用一个文件作为参数调用 importOneContractESTD(例如,将 #{stepExecutionContext[inputfile]} 替换为 ${my.file}),它有效......但我想尝试使用spring批处理来管理我的目录而不是我的调用shell脚本......

感谢您的想法!

【问题讨论】:

    标签: spring spring-batch executioncontext


    【解决方案1】:

    需要访问stepExecutionContext时添加scope="step"

    喜欢这里:

    <bean id="md5Tasklet" class="com.sopra.banking.cirbe.acquisition.batch.AcquisitionMD5Tasklet" scope="step">
        <property name="file" value="#{stepExecutionContext[inputfile]}" />
    </bean> 
    

    更多信息here

    【讨论】:

    • 谢谢dimzak。我做到了,报价也丢失了:#{stepExecutionContext['inputfile']}。但是现在,我得到的是 FlowJob: [name=importContractESTD]] 完成了以下参数:[{}] 和以下状态:[COMPLETED],当然,它不处理我的文件......跨度>
    • 尝试删除引号,因为 Spring Batch 现在检查“'inputfile'”而不是“inputfile”。也许添加一个像 here 这样的侦听器会很好,第 1 节。 11.7 所以作业在找不到输入文件时会返回失败
    • 另一个值得一看的东西:“file:${import.contract.filePattern}”。也许最好这样写:“file:${import.contract.filePattern}/*” 告诉 Spring Batch 处理该文件夹中的所有文件
    • 实际上,import.contract.filePattern = /myDirectory/*.txt 在我的属性文件中。我按照您的建议留下了引号,并打算让一个听众试图理解为什么没有文件可以执行任何东西......因为“stepJob”没有启动,所以什么也没做。但是为什么不推出,这是个问题,呵呵。我添加了我的 jobParametersExtractor 中缺少的属性 ,但无论我更改什么似乎都没有任何效果......
    • 嗯,Listener 将帮助您确定问题是否是输入。从您的第一条评论开始:jobParamExtractor 无法正常工作 - 未找到输入文件。再次,使用引号,我认为它们是不需要的。