Spring batch 使用MultiResourceItemReader时没有要读取的资源错误
我正在从S3存储桶下载文件,然后尝试使用MultiResourceItemReader读取,因为存储桶中可能有多个csv文件 我可以下载文件并将其放在我的本地计算机上,但我无法读取文件,文件不在类路径中。我正在传递完整的文件路径以读取文件,但某些内容未按预期工作。我得到:没有资源阅读。如果这应该是一个错误条件,则设置strict=true。 我可能没有正确传递文件路径 自定义日志:Spring batch 使用MultiResourceItemReader时没有要读取的资源错误,spring-batch,Spring Batch,我正在从S3存储桶下载文件,然后尝试使用MultiResourceItemReader读取,因为存储桶中可能有多个csv文件 我可以下载文件并将其放在我的本地计算机上,但我无法读取文件,文件不在类路径中。我正在传递完整的文件路径以读取文件,但某些内容未按预期工作。我得到:没有资源阅读。如果这应该是一个错误条件,则设置strict=true。 我可能没有正确传递文件路径 自定义日志: 2021-04-21 00:32:09.690 INFO 106084 --- [ restartedMain
2021-04-21 00:32:09.690 INFO 106084 --- [ restartedMain] c.c.S.I.TaskletS3DownloadFiles : Started Downloading files from S3 bucket..
2021-04-21 00:32:10.086 INFO 106084 --- [ restartedMain] c.c.S.Config.S3BucketConfig : The input file : MI4275/input/MI4275sample.csv, has been successfully copied to : C:\Users\Desktop\data\in\MI4275sample.csv, and the file size is : 239505 bytes
2021-04-21 00:32:11.369 INFO 106084 --- [ restartedMain] o.s.batch.core.step.AbstractStep : Step: [step1MI4275S3ListCopyFiles] executed in 4s697ms
2021-04-21 00:32:16.475 INFO 106084 --- [ restartedMain] o.s.batch.core.job.SimpleStepHandler : Executing step: [step1ReadLoadMI4275CSV]
2021-04-21 00:32:17.477 WARN 106084 --- [ restartedMain] o.s.b.item.file.MultiResourceItemReader : No resources to read. Set strict=true if this should be an error condition.
2021-04-21 00:32:20.686 INFO 106084 --- [ restartedMain] o.s.batch.core.step.AbstractStep : Step: [step1ReadLoadMI4275CSV] executed in 4s210ms
2021-04-21 00:32:23.960 INFO 106084 --- [ restartedMain] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=jobCSProvMI4275]] completed with the following parameters: [{JobID=1618990319394}] and the following status: [COMPLETED] in 20s416ms
@Configuration
@EnableBatchProcessing
public class JobStepBuilderConfig {
@Autowired
JobBuilderFactory jobBuilderFactory;
@Autowired
StepBuilderFactory stepBuilderFactory;
@Autowired
DataSource datasource;
@Autowired
TaskletS3DownloadFiles taskletS3DownloadFiles;
@Value("${local.input.file.path.pattern}")
private Resource[] resources;
String currentDate ;
@Bean
@StepScope
// MultiResourceItemReader to read multiple files sequentially
public MultiResourceItemReader<Provider> providerMultiResourceItemReader() {
MultiResourceItemReader<Provider> multiResourceItemReader = new MultiResourceItemReader<>();
multiResourceItemReader.setResources(resources);
multiResourceItemReader.setDelegate(providerItemReader());
return multiResourceItemReader;
}
@Bean
@StepScope
// FlatfileItemReader to define file properties
public FlatFileItemReader<Provider> providerItemReader(){
// create FlatFileItemReader
FlatFileItemReader<Provider> reader = new FlatFileItemReader<>();
// skip header
reader.setLinesToSkip(1);
DefaultLineMapper<Provider> customerLineMapper = new DefaultLineMapper<>();
// tokenizer for delimited file
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
customerLineMapper.setLineTokenizer(tokenizer);
customerLineMapper.setFieldSetMapper(new ProviderFieldSetMapper());
customerLineMapper.afterPropertiesSet();
reader.setLineMapper(customerLineMapper);
return reader ;
}
@Bean
// JdbcBatchItemWriter to write records into database
public JdbcBatchItemWriter<Provider> providerJdbcBatchItemWriter(){
JdbcBatchItemWriter<Provider> jdbcBatchItemWriter = new JdbcBatchItemWriter<>();
jdbcBatchItemWriter.setDataSource(this.datasource);
jdbcBatchItemWriter.setSql(insertQuery);
jdbcBatchItemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
jdbcBatchItemWriter.afterPropertiesSet();
return jdbcBatchItemWriter;
}
// Steps
@Bean
public Step step1(){
// step 1 : Read records from custom table and call stored procedure to update facets table
return stepBuilderFactory.get("step1S3ListCopyFiles")
.tasklet(taskletS3DownloadFiles)
.build();
}
@Bean
public Step step2(){
// step 2 : Read csv files and dump it into a custom table
return stepBuilderFactory.get("step2ReadLoadCSV")
.<Provider, Provider>chunk(1000)
.reader(providerMultiResourceItemReader())
.writer(providerJdbcBatchItemWriter())
.build();
}
// Job
@Bean
public Job job(){
return jobBuilderFactory.get("jobCSProvMI")
.start(step1())
.next(step2())
.incrementer(new RunIdIncrementer())
.build();
}
}
代码:
2021-04-21 00:32:09.690 INFO 106084 --- [ restartedMain] c.c.S.I.TaskletS3DownloadFiles : Started Downloading files from S3 bucket..
2021-04-21 00:32:10.086 INFO 106084 --- [ restartedMain] c.c.S.Config.S3BucketConfig : The input file : MI4275/input/MI4275sample.csv, has been successfully copied to : C:\Users\Desktop\data\in\MI4275sample.csv, and the file size is : 239505 bytes
2021-04-21 00:32:11.369 INFO 106084 --- [ restartedMain] o.s.batch.core.step.AbstractStep : Step: [step1MI4275S3ListCopyFiles] executed in 4s697ms
2021-04-21 00:32:16.475 INFO 106084 --- [ restartedMain] o.s.batch.core.job.SimpleStepHandler : Executing step: [step1ReadLoadMI4275CSV]
2021-04-21 00:32:17.477 WARN 106084 --- [ restartedMain] o.s.b.item.file.MultiResourceItemReader : No resources to read. Set strict=true if this should be an error condition.
2021-04-21 00:32:20.686 INFO 106084 --- [ restartedMain] o.s.batch.core.step.AbstractStep : Step: [step1ReadLoadMI4275CSV] executed in 4s210ms
2021-04-21 00:32:23.960 INFO 106084 --- [ restartedMain] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=jobCSProvMI4275]] completed with the following parameters: [{JobID=1618990319394}] and the following status: [COMPLETED] in 20s416ms
@Configuration
@EnableBatchProcessing
public class JobStepBuilderConfig {
@Autowired
JobBuilderFactory jobBuilderFactory;
@Autowired
StepBuilderFactory stepBuilderFactory;
@Autowired
DataSource datasource;
@Autowired
TaskletS3DownloadFiles taskletS3DownloadFiles;
@Value("${local.input.file.path.pattern}")
private Resource[] resources;
String currentDate ;
@Bean
@StepScope
// MultiResourceItemReader to read multiple files sequentially
public MultiResourceItemReader<Provider> providerMultiResourceItemReader() {
MultiResourceItemReader<Provider> multiResourceItemReader = new MultiResourceItemReader<>();
multiResourceItemReader.setResources(resources);
multiResourceItemReader.setDelegate(providerItemReader());
return multiResourceItemReader;
}
@Bean
@StepScope
// FlatfileItemReader to define file properties
public FlatFileItemReader<Provider> providerItemReader(){
// create FlatFileItemReader
FlatFileItemReader<Provider> reader = new FlatFileItemReader<>();
// skip header
reader.setLinesToSkip(1);
DefaultLineMapper<Provider> customerLineMapper = new DefaultLineMapper<>();
// tokenizer for delimited file
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
customerLineMapper.setLineTokenizer(tokenizer);
customerLineMapper.setFieldSetMapper(new ProviderFieldSetMapper());
customerLineMapper.afterPropertiesSet();
reader.setLineMapper(customerLineMapper);
return reader ;
}
@Bean
// JdbcBatchItemWriter to write records into database
public JdbcBatchItemWriter<Provider> providerJdbcBatchItemWriter(){
JdbcBatchItemWriter<Provider> jdbcBatchItemWriter = new JdbcBatchItemWriter<>();
jdbcBatchItemWriter.setDataSource(this.datasource);
jdbcBatchItemWriter.setSql(insertQuery);
jdbcBatchItemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
jdbcBatchItemWriter.afterPropertiesSet();
return jdbcBatchItemWriter;
}
// Steps
@Bean
public Step step1(){
// step 1 : Read records from custom table and call stored procedure to update facets table
return stepBuilderFactory.get("step1S3ListCopyFiles")
.tasklet(taskletS3DownloadFiles)
.build();
}
@Bean
public Step step2(){
// step 2 : Read csv files and dump it into a custom table
return stepBuilderFactory.get("step2ReadLoadCSV")
.<Provider, Provider>chunk(1000)
.reader(providerMultiResourceItemReader())
.writer(providerJdbcBatchItemWriter())
.build();
}
// Job
@Bean
public Job job(){
return jobBuilderFactory.get("jobCSProvMI")
.start(step1())
.next(step2())
.incrementer(new RunIdIncrementer())
.build();
}
}
您正在用
@Component
注释的类中声明bean定义方法(用@bean
注释的方法providerMultiResourceItemReader()
)。这是不对的。您应该在用@Configuration
注释的类中声明bean
我认为没有必要使用@组件公共类FileItemReader{..}
类,您可以在定义步骤的同一类中定义读取器,类似于:
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
@Configuration
@EnableBatchProcessing
public class MyJobConfiguration {
@Bean
public ItemReader<Integer> itemReader() {
return new ListItemReader<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
}
@Bean
public ItemWriter<Integer> itemWriter() {
return items -> items.forEach(System.out::println);
}
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<Integer, Integer>chunk(5)
.reader(itemReader())
.writer(itemWriter())
.build())
.build();
}
}
然后在主作业配置中导入该类:
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(ItemReaderConfiguration.class)
@EnableBatchProcessing
public class MyJobConfiguration {
@Bean
public ItemWriter<Integer> itemWriter() {
return items -> items.forEach(System.out::println);
}
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, ItemReader<Integer> itemReader) {
return jobs.get("job")
.start(steps.get("step")
.<Integer, Integer>chunk(5)
.reader(itemReader)
.writer(itemWriter())
.build())
.build();
}
}
import org.springframework.batch.core.Job;
导入org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
导入org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
导入org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
导入org.springframework.batch.item.ItemReader;
导入org.springframework.batch.item.ItemWriter;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.context.annotation.import;
@配置
@导入(ItemReaderConfiguration.class)
@启用批处理
公共类MyJobConfiguration{
@豆子
公共ItemWriter ItemWriter(){
返回项目->项目.forEach(系统输出::println);
}
@豆子
公共作业作业(JobBuilderFactory作业、StepBuilderFactory步骤、ItemReader ItemReader){
返回作业。获取(“作业”)
.开始(步骤.获取(“步骤”)
.chunk(5)
.reader(itemReader)
.writer(itemWriter())
.build())
.build();
}
}
感谢您的回复,但我仍然收到:没有资源阅读错误。如何在multiResourceItemReader中传递绝对路径…?您现在如何传递它们?请编辑您的问题并与您分享最新的设置。Ben,我已经更新了代码。你能检查确认一下吗?我把tasklet放在另一个类中,因为它在一个类文件中的代码太多了。看起来当我第二次运行它时,它正在被执行。不确定,差距在哪里?我保存了文件,只运行了步骤2,它拾取文件意味着模式没有问题。当我删除文件并运行步骤2时,它抛出了相同的错误。看起来文件在步骤1中被复制,但是当步骤2以某种方式执行时,即使文件可用,也无法识别。。不知道为什么?