Search code examples
javaspringspring-bootspring-batch

Spring batch - How to set each csv file name that I am reading into my entity?


How to set each csv file name that I am reading in my entity and send this to processor, I have the following reader code:

In the following entity, I have the field fileName that I want to set with the currently csv file name that I am reading, the other field I want to set with the csv data.

Entity:

@Data
@AllArgsConstructor
public class TestDTO {
    private String fileName;
    private String name;
    private String lastName;
}

Code:

@Configuration
public class testReader{
    @Bean
    public FlatFileItemReader<TestDTO> csvFileReader() {
        FlatFileItemReader<TestDTO> reader = new FlatFileItemReader<>();
        reader.linesToSkip(1) // Skip header row if needed
        reader.lineMapper(csvLineMapper())
        return reader;
    }

    @Bean("testReader")
    public MultiResourceItemReader<testDTO> multiResourceReader() throws IOException {
        Resource[] files = csvFileResource();
        MultiResourceItemReader<testDTO> resourceItemReader = new MultiResourceItemReader<>();
        resourceItemReader.setResources(files);
        resourceItemReader.setDelegate(csvFileReader());
        return resourceItemReader;
    }

    @Bean
    public DefaultLineMapper<TestDTO> csvLineMapper() {
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        tokenizer.setNames("Name","Lastname");

        BeanWrapperFieldSetMapper<YourDataClass> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
        fieldSetMapper.setTargetType(TestDTO.class);

        DefaultLineMapper<TestDTO> lineMapper = new DefaultLineMapper<>();
        lineMapper.setLineTokenizer(tokenizer);
        lineMapper.setFieldSetMapper(fieldSetMapper);

        return lineMapper;
    }

    @Bean
    public Resource[] csvFileResource() throws IOException {
        // Specify the folder path where your CSV files are generated
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources("file:input/*.csv");
        if (resources.length == 0) {
            throw new FileNotFoundException("No CSV files found in the specified folder.");
        }
        return resources;
    }
}

Solution

  • You could make your TestDTO implement the ResourceAware interface...

    @Data
    public class TestDTO implements ResourceAware {
        private String fileName;
        private String name;
        private String lastName;
    
        public void setResource(Resource resource) {
            this.fileName = resource.getFilename();
        }
    }