javaspring-bootspring-batchopencsvcsvtojson

Configuring openCSV instead of FlatFileItemReader in spring batch step


I am trying to configure openCSV in the reader() step in the spring batch to directly convert a record read from a CSV file into a JAVA POJO. But I am running into the issue of how to correctly set the lineMapper with the openCSV.

As suggested in the post linked here How to replace flatFileItemReader with openCSV in spring batch, I am trying as below:

public Event reader() throws IOException {
        FlatFileItemReader<Event> itemReader = new FlatFileItemReader<Event>();
        itemReader.setLineMapper(lineMapper());
        itemReader.setLinesToSkip(1);
        itemReader.setResource(new FileSystemResource(inputFilePath));
        return itemReader;
    }

But I am not able to figure out how to configure the lineMapper:

    public LineMapper<Event> lineMapper() throws IOException {
       DefaultLineMapper<Event> lineMapper = new DefaultLineMapper<Event>();
       DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer("\t");
       BeanWrapperFieldSetMapper<Event> fieldSetMapper = new BeanWrapperFieldSetMapper<Event>();
       fieldSetMapper.setTargetType(Event.class);
       lineMapper.setLineTokenizer(???);
       lineMapper.setFieldSetMapper(???);

I have the code to read the file and convert it to the desired POJO but where to put it:

        try (
                Reader reader = Files.newBufferedReader(Paths.get(inputFilePath));
        ) {
            CsvToBean<Event> csvToBean = new CsvToBeanBuilder(reader)
                    .withSkipLines(1)
                    .withType(Event.class)
                    .withIgnoreLeadingWhiteSpace(true)
                    .build();
            return csvToBean.iterator().next();
        }

Any help to point me in the right direction is highly appreciated.


Solution

  • You are using the DefaultLineMapper and trying to set a LineTokenizer and FieldSetMapper in it, but this is not what is mentioned in the link you shared.

    You need a custom implementation of the LineMapper interface that is based on OpenCSV:

    public class OpenCSVLineMapper<T> implements LineMapper<T> {
        
        @Override
        public T mapLine(String line, int lineNumber) throws Exception {
            // TODO use OpenCSV to map a line to a POJO of type T
            return null;
        }
    }
    

    OpenCSV provides APIs to both read the file and map data to objects. You don't need the reading part as this will be done by the FlatFileItemReader from Spring Batch, you only need to use OpenCSV for the mapping part.

    Once this in place, you can set your OpenCSV based line mapper implementation on the FlatFileItemReader:

    public FlatFileItemReader<Event> reader() throws IOException {
       FlatFileItemReader<Event> itemReader = new FlatFileItemReader<Event>();
       itemReader.setResource(new FileSystemResource(inputFilePath));
       itemReader.setLinesToSkip(1);
       itemReader.setLineMapper(new OpenCSVLineMapper<>());
       return itemReader;
    }