Spring batch 使用MultiResourceItemReader时没有要读取的资源错误

Spring batch 使用MultiResourceItemReader时没有要读取的资源错误,spring-batch,Spring Batch,我正在从S3存储桶下载文件,然后尝试使用MultiResourceItemReader读取,因为存储桶中可能有多个csv文件 我可以下载文件并将其放在我的本地计算机上,但我无法读取文件,文件不在类路径中。我正在传递完整的文件路径以读取文件,但某些内容未按预期工作。我得到:没有资源阅读。如果这应该是一个错误条件,则设置strict=true。 我可能没有正确传递文件路径 自定义日志: 2021-04-21 00:32:09.690 INFO 106084 --- [ restartedMain

我正在从S3存储桶下载文件,然后尝试使用MultiResourceItemReader读取,因为存储桶中可能有多个csv文件

我可以下载文件并将其放在我的本地计算机上,但我无法读取文件,文件不在类路径中。我正在传递完整的文件路径以读取文件,但某些内容未按预期工作。我得到:没有资源阅读。如果这应该是一个错误条件,则设置strict=true。 我可能没有正确传递文件路径

自定义日志:

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以某种方式执行时,即使文件可用,也无法识别。。不知道为什么?