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

Spring Batch:如何将读取的CSV文件名存入实体并传递给处理器

解决Spring Batch中给TestDTO设置当前CSV文件名的问题

要实现读取CSV数据时将当前文件名填充到TestDTO的fileName字段,同时保留name和lastName的正常映射,可以通过以下两种方案实现:

方案一:自定义FlatFileItemReader子类(推荐)

通过扩展FlatFileItemReader,在读取数据后直接设置文件名,无需额外监听器配置:

  1. 创建自定义Reader类
public class FileNameAwareFlatFileItemReader extends FlatFileItemReader<TestDTO> {

    @Override
    protected TestDTO doRead() throws Exception {
        TestDTO item = super.doRead();
        if (item != null) {
            // 获取当前正在读取的CSV资源
            Resource currentResource = getCurrentResource();
            if (currentResource != null) {
                // 设置文件名(如需全路径可使用currentResource.getURI().getPath())
                item.setFileName(currentResource.getFilename());
            }
        }
        return item;
    }
}
  1. 修改原Reader配置
    将原csvFileReader方法中的FlatFileItemReader替换为自定义实现:
@Bean
public FlatFileItemReader<TestDTO> csvFileReader() {
    FileNameAwareFlatFileItemReader reader = new FileNameAwareFlatFileItemReader();
    reader.linesToSkip(1); // 跳过表头行
    reader.setLineMapper(csvLineMapper());
    return reader;
}

方案二:使用ItemReadListener监听读取事件

通过读取监听器在读取完成后为TestDTO设置文件名:

  1. 创建读取监听器类
@Component
public class TestDTOResourceListener implements ItemReadListener<TestDTO> {

    @Autowired
    private FlatFileItemReader<TestDTO> csvFileReader;

    @Override
    public void afterRead(TestDTO item) {
        Resource currentResource = csvFileReader.getCurrentResource();
        if (currentResource != null) {
            item.setFileName(currentResource.getFilename());
        }
    }

    @Override
    public void beforeRead() {}

    @Override
    public void onReadError(Exception ex) {}
}
  1. 在Step中注册监听器
    配置Step时添加该监听器,确保读取完成后触发文件名设置:
@Bean
public Step csvProcessingStep(ItemReader<TestDTO> testReader, 
                              ItemProcessor<TestDTO, TestDTO> testProcessor,
                              ItemWriter<TestDTO> testWriter,
                              TestDTOResourceListener readListener) {
    return stepBuilderFactory.get("csvProcessingStep")
            .<TestDTO, TestDTO>chunk(10)
            .reader(testReader)
            .processor(testProcessor)
            .writer(testWriter)
            .listener(readListener)
            .build();
}

额外注意事项

原代码中DelimitedLineTokenizer的列名是"Name","Lastname",而TestDTO的字段是name和lastName,为确保映射准确,建议将列名修改为与字段名一致:

tokenizer.setNames("name", "lastName");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:17:14