Spring批处理-验证输入csv文件中的标题行,如果无效,则跳过该文件

Spring批处理-验证输入csv文件中的标题行,如果无效,则跳过该文件,spring,file,spring-batch,skip,Spring,File,Spring Batch,Skip,我有一个简单的工作如下: <batch:step id="step"> <batch:tasklet> <batch:chunk reader="itemReader" processor="itemProcessor" writer="itemWriter" commit- interval="5000" /> </batch:tasklet> </batch:step> <bean id="itemReader

我有一个简单的工作如下:

<batch:step id="step">
 <batch:tasklet>
  <batch:chunk reader="itemReader" processor="itemProcessor" writer="itemWriter" commit-    interval="5000" />
 </batch:tasklet>
</batch:step>
<bean id="itemReader" class="org.springframework.batch.item.file.FlatFileItemReader"
scope="step">
 <property name="linesToSkip" value="1"></property>
 <property name="skippedLinesCallback" ref="skippedLinesCallback" ></property>

 <property name="lineMapper">
    <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                <property name="lineTokenizer" ref="lineTokenizer">                
                <property name="delimiter" value="," />                    
            </bean>
        </property>
        <property name="fieldSetMapper">
            <bean
                class="org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper" />
        </property>
    </bean>
</property>
<property name="resource" value="#{stepExecutionContext['inputKeyName']}" />
</bean>

<bean id"lineTokenizer"                        class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">

<bean id="skippedLinesCallback" class="com.test.IteMReaderHeader" >
<property name="lineTokenizer" ref="lineTokenizer">
</bean>

itemReader如下所示:

<batch:step id="step">
 <batch:tasklet>
  <batch:chunk reader="itemReader" processor="itemProcessor" writer="itemWriter" commit-    interval="5000" />
 </batch:tasklet>
</batch:step>
<bean id="itemReader" class="org.springframework.batch.item.file.FlatFileItemReader"
scope="step">
 <property name="linesToSkip" value="1"></property>
 <property name="skippedLinesCallback" ref="skippedLinesCallback" ></property>

 <property name="lineMapper">
    <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                <property name="lineTokenizer" ref="lineTokenizer">                
                <property name="delimiter" value="," />                    
            </bean>
        </property>
        <property name="fieldSetMapper">
            <bean
                class="org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper" />
        </property>
    </bean>
</property>
<property name="resource" value="#{stepExecutionContext['inputKeyName']}" />
</bean>

<bean id"lineTokenizer"                        class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">

<bean id="skippedLinesCallback" class="com.test.IteMReaderHeader" >
<property name="lineTokenizer" ref="lineTokenizer">
</bean>

我通过在“com.test.IteMReaderHeader”类中注入“lineTokenizer”来设置输入字段的“名称”

我需要使用固定的标题值验证输入csv文件中的第一行标题行,如果标题行无效,则在这种情况下,我需要失败该步骤并跳过整个文件,以便可以使用下一个文件进行读取

请建议一个合适的实现方法。 我非常感谢你的时间和宝贵的投入


谢谢

管理
FlatFileItemReader
文件停止条件的查找代码

  • 使用私有字段
    布尔noInput
  • 在受保护的
    doRead()中使用私有
    函数readLine()
  • 最好的解决方案是从skippedLineCallback中抛出运行时异常,并将错误作为读卡器耗尽条件进行管理

    例如,以这种方式编写您的委托

    class SkippableItemReader<T> implements ItemStreamReader<T> {
      private ItemStreamReader<T> flatFileItemReader;
      private boolean headerError = false;
    
      void open(ExecutionContext executionContext) throws ItemStreamException {
        try {
          flatFileItemReader.open(executionContext);
        } catch(MyCustomExceptionHeaderErrorException e) {
          headerError = true;
        }
      }
    
      public T read() {
        if(headerError)
          return null;
        return flatFileItemReader.read();
      }
    
      // Other functions delegation
    }
    
    代码是直接编写的,没有经过测试,因此可能会有错误,但我希望您能理解我的观点。

    希望能解决您的问题

    谢谢您的投入。第二种方法(扩展FlatFileItemReader)运行良好。使用第1种方法(即实现ItemStreamReader)时也出现了一些问题。在上述场景中,是否有可能使步骤失败,但仍然跳过文件?可能在步骤(或作业)执行上下文中保留headerError值,并在doOpen()/doUpdate()/doClose()或使用侦听器对其进行管理。对不起,我从来没有试过,很有帮助。谢谢@LucaBassoRicci