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

Spring Batch如何避免IllegalStateException:输入资源必须存在

解决方案

要实现输入文件缺失时不终止批处理且生成指定输出文件的需求,可以通过流程分支判断+专用处理步骤来实现,具体如下:

1. 新增文件存在性判断决策器

创建JobExecutionDecider实现类,用于在作业启动前判断输入文件是否存在,以此决定后续执行的流程:

@Component
public class InputFileDecider implements JobExecutionDecider {

    @Value("${inputFolder}") // 注入配置的输入文件夹路径
    private String inputFolder;

    @Override
    public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
        File inputFile = new File(inputFolder.concat(File.separator).concat("my-input-file.csv"));
        boolean isFileValid = inputFile.exists() && inputFile.isFile();
        return isFileValid ? 
            new FlowExecutionStatus("FILE_EXISTS") : 
            new FlowExecutionStatus("FILE_MISSING");
    }
}

2. 定义两种流程的Step

2.1 正常处理Step(文件存在时执行)

保留你原有的reader、processor和writer配置,构建标准的读-处理-写Step:

@Bean
public Step normalStep(StepBuilderFactory stepBuilderFactory,
                       FlatFileItemReader<MyClass> reader,
                       ItemProcessor<MyClass, MyClass> processor,
                       FlatFileItemWriter<MyClass> normalOutputWriter) {
    return stepBuilderFactory.get("normalStep")
            .<MyClass, MyClass>chunk(100) // 根据实际需求调整chunk大小
            .reader(reader)
            .processor(processor)
            .writer(normalOutputWriter)
            .build();
}

// 正常输出文件的Writer
@Bean
public FlatFileItemWriter<MyClass> normalOutputWriter(@Value("${outputFolder}") String outputFolder) {
    return new FlatFileItemWriterBuilder<MyClass>()
            .name("normalOutputWriter")
            .resource(new FileSystemResource(outputFolder.concat(File.separator).concat("normal-output.csv")))
            .delimited()
            .names("field1", "field2")
            .build();
}

2.2 文件缺失处理Step(文件不存在时执行)

创建一个TaskletStep,专门用于生成文件缺失时的输出文件:

@Bean
public Step noInputStep(StepBuilderFactory stepBuilderFactory, @Value("${outputFolder}") String outputFolder) {
    return stepBuilderFactory.get("noInputStep")
            .tasklet((contribution, chunkContext) -> {
                String outputPath = outputFolder.concat(File.separator).concat("no-input-output.csv");
                File outputFile = new File(outputPath);
                
                // 写入自定义内容(比如表头+提示信息)
                try (PrintWriter writer = new PrintWriter(outputFile)) {
                    writer.println("field1,field2");
                    writer.println("无输入数据,无输入数据");
                } catch (FileNotFoundException e) {
                    throw new RuntimeException("生成无输入输出文件失败", e);
                }
                return RepeatStatus.FINISHED;
            })
            .build();
}

3. 配置Job的流程分支

将决策器和两个Step整合到Job中,实现分支逻辑:

@Bean
public Job batchJob(JobBuilderFactory jobBuilderFactory,
                    Step normalStep,
                    Step noInputStep,
                    InputFileDecider inputFileDecider) {
    return jobBuilderFactory.get("batchJob")
            .start(inputFileDecider)
            .on("FILE_EXISTS").to(normalStep) // 文件存在时执行正常处理流程
            .on("FILE_MISSING").to(noInputStep) // 文件缺失时执行专用生成流程
            .end()
            .build();
}

4. 保留原Reader的Strict模式(可选)

由于决策器已经确保只有文件存在时才会执行normalStep,你原有的reader可以保留strict模式(默认开启),这样如果正常流程中文件意外丢失,会及时抛出异常,避免静默处理带来的风险:

@SuppressWarnings("unchecked")
@Bean
public FlatFileItemReader<MyClass> reader(@Value("${inputFolder}") String inputFolder) {
    BeanWrapperFieldSetMapper beanWrapperMapper = new BeanWrapperFieldSetMapper<MyClass>();
    beanWrapperMapper.setTargetType(MyClass.class);

    return new FlatFileItemReaderBuilder<MyClass>()
            .name("MyClassReader")
            .resource(new FileSystemResource(inputFolder.concat(File.separator).concat("my-input-file.csv")))
            .delimited()
            .names("field1", "field2")
            .fieldSetMapper(beanWrapperMapper)
            // 无需修改strict模式,默认true,确保正常流程中文件必须存在
            .build();
}

工作流程说明

  1. 作业启动后,首先通过InputFileDecider判断输入文件是否存在;
  2. 若文件存在,执行正常的读-处理-写Step,生成常规输出文件;
  3. 若文件缺失,直接执行noInputStep,生成指定的无输入提示文件;
  4. 两种流程都会正常结束批处理,不会因文件缺失抛出异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:45:46