Spring Batch多CSV合并任务完成但输出文件无数据求助
问题:Spring Batch合并多CSV文件后输出为空
尝试使用Spring Batch读取resources/input目录下所有命名为user_*.csv的多份CSV文件,合并后写入resources/output/user.csv文件。执行过程无报错,但输出文件中没有数据,请求排查原因。
配置文件
@Configuration @EnableBatchProcessing public class BatchConfig { private static final Logger log = LoggerFactory.getLogger(BatchConfig.class); @Autowired private StepBuilderFactory stepBuilderFactory; @Autowired private JobBuilderFactory jobBuilderFactory; @Value(value = "classpath:input/user_*.csv") private Resource[] resources; @Bean public FlatFileItemReader<User> flatFileItemReader(){ log.info("flatFileItemReader execution started"); FlatFileItemReader<User> reader = new FlatFileItemReader<>(); reader.setName("ReadMultipleCsv"); reader.setLineMapper(lineMapper()); log.info("flatFileItemReader execution completed"); return reader; } private LineMapper<User> lineMapper(){ DefaultLineMapper<User> lineMapper = new DefaultLineMapper<>(); DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer(); lineTokenizer.setDelimiter(","); lineTokenizer.setStrict(false); lineTokenizer.setNames(new String[] {"id","name","department","salary"}); BeanWrapperFieldSetMapper<User> fieldSetMapper = new BeanWrapperFieldSetMapper<>(); fieldSetMapper.setTargetType(User.class); lineMapper.setLineTokenizer(lineTokenizer); lineMapper.setFieldSetMapper(fieldSetMapper); return lineMapper; } @Bean public MultiResourceItemReader<User> multiResourceItemReader(){ log.info("multiResourceItemReader() execution started"); MultiResourceItemReader<User> reader = new MultiResourceItemReader<>(); reader.setResources(resources); reader.setDelegate(flatFileItemReader()); log.info("multiResourceItemReader() execution completed"); return reader; } @Bean public FlatFileItemWriter<User> writer(){ log.info("writer() execution started"); FlatFileItemWriter<User> writer = new FlatFileItemWriter<>(); writer.setResource(new ClassPathResource("output/user.csv")); writer.setAppendAllowed(true); DelimitedLineAggregator<User> delimitedLineAggregator = new DelimitedLineAggregator<>(); delimitedLineAggregator.setDelimiter(","); BeanWrapperFieldExtractor<User> beanWrapperFieldExtractor = new BeanWrapperFieldExtractor<>(); beanWrapperFieldExtractor.setNames(new String[] {"id","name","department","salary"}); delimitedLineAggregator.setFieldExtractor(beanWrapperFieldExtractor); writer.setLineAggregator(delimitedLineAggregator); log.info("writer() execution completed"); return writer; } @Bean public Step step(){ return stepBuilderFactory.get("get-student").<User, User>chunk(5) .reader(multiResourceItemReader()) .writer(writer()).build(); } @Bean public Job job(){ return jobBuilderFactory.get("process-student").incrementer(new RunIdIncrementer()) .flow(step()).end().build(); } }
User实体类
@Getter @Setter @AllArgsConstructor @NoArgsConstructor public class User { private String id; private String name; private String department; private String salary; }
执行日志
2022-08-22 16:40:06.295 INFO 17264 --- [ main] c.s.SpringBatchMultipleCsvToApplication : Starting SpringBatchMultipleCsvToApplication using Java 1.8.0_121 on GBMLVVCSW3823 with PID 17264 (C:\Users\NavghS\Downloads\spring-batch-multiple-csv-to\spring-batch-multiple-csv-to\target\classes started by NavghS in C:\Users\NavghS\Downloads\spring-batch-multiple-csv-to\spring-batch-multiple-csv-to) 2022-08-22 16:40:06.300 INFO 17264 --- [ main] c.s.SpringBatchMultipleCsvToApplication : No active profile set, falling back to 1 default profile: "default" 2022-08-22 16:40:08.999 INFO 17264 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2022-08-22 16:40:09.017 INFO 17264 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2022-08-22 16:40:09.018 INFO 17264 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.65] 2022-08-22 16:40:09.349 INFO 17264 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2022-08-22 16:40:09.350 INFO 17264 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2936 ms 2022-08-22 16:40:09.542 INFO 17264 --- [ main] com.shrikant.config.BatchConfig : flatFileItemReader execution started 2022-08-22 16:40:09.554 INFO 17264 --- [ main] com.shrikant.config.BatchConfig : flatFileItemReader execution completed 2022-08-22 16:40:09.559 INFO 17264 --- [ main] com.shrikant.config.BatchConfig : multiResourceItemReader() execution started 2022-08-22 16:40:09.574 INFO 17264 --- [ main] com.shrikant.config.BatchConfig : multiResourceItemReader() execution completed 2022-08-22 16:40:09.576 INFO 17264 --- [ main] com.shrikant.config.BatchConfig : writer() execution started 2022-08-22 16:40:09.579 INFO 17264 --- [ main] com.shrikant.config.BatchConfig : writer() execution completed 2022-08-22 16:40:10.299 INFO 17264 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2022-08-22 16:40:10.313 INFO 17264 --- [ main] c.s.SpringBatchMultipleCsvToApplication : Started SpringBatchMultipleCsvToApplication in 5.205 seconds (JVM running for 6.176) 2022-08-22 16:40:10.316 INFO 17264 --- [ main] o.s.b.a.b.JobLauncherApplicationRunner : Running default command line with: [] 2022-08-22 16:40:10.317 WARN 17264 --- [ main] o.s.b.c.c.a.DefaultBatchConfigurer : No datasource was provided...using a Map based JobRepository 2022-08-22 16:40:10.318 WARN 17264 --- [ main] o.s.b.c.c.a.DefaultBatchConfigurer : No transaction manager was provided, using a ResourcelessTransactionManager 2022-08-22 16:40:10.339 INFO 17264 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor. 2022-08-22 16:40:10.393 INFO 17264 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=process-student]] launched with the following parameters: [{run.id=1}] 2022-08-22 16:40:10.612 INFO 17264 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [get-student] 2022-08-22 16:40:10.894 INFO 17264 --- [ main] o.s.batch.core.step.AbstractStep : Step: [get-student] executed in 282ms 2022-08-22 16:40:10.907 INFO 17264 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=process-student]] completed with the following parameters: [{run.id=1}] and the following status: [COMPLETED] in 344ms
排查关键点
- 验证资源加载情况:在
multiResourceItemReader方法中添加日志打印resources.length,确认是否成功加载到目标CSV文件。如果长度为0,说明路径匹配失败,检查resources/input目录是否存在、文件名是否符合user_*.csv格式。 - 跳过CSV表头:如果输入CSV文件包含表头行,需在
flatFileItemReader中设置reader.setLinesToSkip(1);,否则表头会被尝试解析为User对象,可能导致数据无法正确读取(即使strict=false不报错,也可能没有有效数据输出)。 - 修改写入资源路径:
ClassPathResource指向的是类路径下的只读资源,运行时写入可能无法生效或写入到编译后的target/classes/output目录而非源码目录。建议改用FileSystemResource指定具体文件路径,比如:
或者检查writer.setResource(new FileSystemResource("src/main/resources/output/user.csv"));target/classes/output/user.csv是否有数据。 - 添加数据读取验证:新增
ItemProcessor打印读取到的User对象,确认是否真的读取到数据:
然后在Step配置中添加@Bean public ItemProcessor<User, User> processor() { return user -> { log.info("读取到用户数据:{}", user); return user; }; }.processor(processor())。
内容的提问来源于stack exchange,提问作者breakingcode
相关产品推荐
相关产品推荐

