You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Batch FlatFileItemReader遇错误令牌数如何继续执行?

当然可以搞定这个问题!Spring Batch其实已经内置了成熟的机制来处理坏行场景,根本不用你自己去扩展FlatFileItemReader,下面给你几个最实用的最佳方案:

方案一:利用Spring Batch的Skip容错机制(官方推荐)

这是处理此类问题最优雅的方式,Spring Batch的faultTolerant()配置专门用来处理读取/处理/写入过程中的异常,你只需要指定要跳过的异常类型和最大跳过次数即可,遇到符合条件的坏行时,框架会自动跳过并继续执行,直到达到跳过上限才会终止任务。

配置示例

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.SkipListener;
import org.springframework.batch.core.step.builder.StepBuilderFactory;
import org.springframework.batch.item.file.FlatFileParseException;
import org.springframework.context.annotation.Bean;

@Bean
public Step csvProcessingStep(ItemReader<MyRecord> reader, 
                              ItemProcessor<MyRecord, MyRecord> processor, 
                              ItemWriter<MyRecord> writer,
                              StepBuilderFactory stepBuilderFactory) {
    Logger log = LoggerFactory.getLogger(this.getClass());
    
    return stepBuilderFactory.get("csvProcessingStep")
            .<MyRecord, MyRecord>chunk(10) // 按10条数据为一个批次处理
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .faultTolerant() // 开启容错模式
            .skip(FlatFileParseException.class) // 指定要跳过的解析异常
            .skipLimit(100) // 最多允许跳过100条坏行,可根据业务调整
            .listener(new SkipListener<MyRecord, MyRecord>() {
                @Override
                public void onSkipInRead(Throwable t) {
                    // 记录坏行的详细信息,方便后续排查
                    if (t instanceof FlatFileParseException) {
                        FlatFileParseException parseException = (FlatFileParseException) t;
                        log.error("跳过解析失败的行,行号:{},原始内容:{}", 
                                  parseException.getLineNumber(), 
                                  parseException.getInput());
                    }
                }
            })
            .build();
}

方案优势

  • 无需修改原有FlatFileItemReader的实现,完全利用框架原生能力
  • 可以精准控制允许跳过的异常类型和数量,避免无限制跳过
  • 通过SkipListener可以轻松记录坏行信息,便于后续分析问题
方案二:自定义包装ItemReader(定制化场景)

如果你的业务需要更细粒度的跳过逻辑(比如根据坏行内容决定是否跳过),可以自己写一个包装类,把FlatFileItemReader作为委托类,手动捕获异常并处理。

实现示例

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.FlatFileParseException;

public class SkipBadLineItemReader<T> implements ItemReader<T> {
    private static final Logger log = LoggerFactory.getLogger(SkipBadLineItemReader.class);
    
    private final FlatFileItemReader<T> delegateReader;
    private final int maxSkipCount;
    private int currentSkipCount = 0;

    public SkipBadLineItemReader(FlatFileItemReader<T> delegateReader, int maxSkipCount) {
        this.delegateReader = delegateReader;
        this.maxSkipCount = maxSkipCount;
    }

    @Override
    public T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
        try {
            return delegateReader.read();
        } catch (FlatFileParseException e) {
            if (currentSkipCount >= maxSkipCount) {
                // 超过跳过上限,抛出异常终止任务
                throw new IllegalStateException("跳过的坏行数量已超过上限:" + maxSkipCount, e);
            }
            currentSkipCount++;
            log.error("跳过坏行,行号:{},内容:{}", e.getLineNumber(), e.getInput());
            // 递归调用read方法,获取下一条有效数据
            return read();
        }
    }
}

使用方式

在配置FlatFileItemReader的地方,用这个包装类包裹起来:

@Bean
public ItemReader<MyRecord> skipBadLineReader() {
    FlatFileItemReader<MyRecord> originalReader = new FlatFileItemReader<>();
    // 配置originalReader的资源、行映射器等...
    
    return new SkipBadLineItemReader<>(originalReader, 100);
}

注意事项

  • 这种方式需要自己管理跳过计数,不如框架的Skip机制集成度高
  • Spring Batch的任务统计(比如跳过行数)可能不会统计到手动跳过的行,需要自己额外记录
总结

优先推荐使用方案一的Skip容错机制,这是Spring Batch官方设计的容错方案,配置简单、功能完善,能满足绝大多数场景的需求。只有当你需要非常定制化的跳过逻辑(比如根据坏行内容做特殊判断)时,再考虑方案二的自定义包装方式。

内容的提问来源于stack exchange,提问作者DavidR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:21:45