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

时间:2013-08-29 18:01:57

标签: 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>

itemReader如下:

<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>

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

我需要验证带有固定标头值的输入csv文件中第一行的标题行,如果标题行无效,那么在这种情况下我需要使步骤失败并跳过整个文件以便下一行文件可用于阅读。

请建议一种合适的方式来实现它。 我非常感谢您的时间和宝贵的意见。

谢谢!

1 个答案:

答案 0 :(得分:4)

管理FlatFileItemReader文件停止条件的代码;

  1. 私有字段boolean noInput
  2. 私有function readLine()在受保护的doRead()
  3. 中使用

    恕我直言,最好的解决方案是从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扩展为

    class SkippableItemReader<T> extends FlatFileItemReader<T> {
      private boolean headerError = false;
    
      protected void doOpen() throws Exception {
        try {
          super.doOpen();
        } catch(MyCustomExceptionHeaderErrorException e) {
          headerError = true;
        }
      }
    
      protected T doRead() throws Exception {
        if(headerError)
          return null;
        return super.doRead();
      }    
    }
    

    代码是在没有测试的情况下直接编写的,因此可能存在错误,但我希望您能理解我的观点 希望可以解决你的问题