Han Nan
Han Nan

Reputation: 117

How to write csv file with empty body using Spring batch

Im using spring boot to write my outbound batch which one of the requirement is to send and empty file with header only if there is no record found.

im using BeanPropertyRowMapper to map my JdbcCursorItemReader... why im using BeanPropertyRowMapper because there is alot column to map. if im using rowmapper it will be hell for me lol. this is the configuration :

    @Bean
public Step RawDataOutBoundSteps() throws IOException {

    return stepBuilderFactory.get("step1").<RawDataExtractionDTO, RawDataExtractionDTO>chunk(1000)//.faultTolerant()
            //.skip(Exception.class)
            //.skipLimit(1000)
            .reader(myDBReader()).processor(myProcessor())
            .writer(myWriter()).build();
}

the problem is, if myDBreader() queries return empty resultset, my code wont go to myProcessor hence myWriter also.

myProcessor :

public class RawDataJobProcessor implements 
ItemProcessor<RawDataExtractionDTO, RawDataExtractionDTO>{

@Override
public RawDataExtractionDTO process(RawDataExtractionDTO item) throws Exception {
    System.out.println(" Raw DAta Process");

    if(item == null )
    return null;

    return item;
}}

my DB reader :

    @Bean
ItemReader<RawDataExtractionDTO> rawDataDBReader() {

    String jobName = Application.jobName;
    String sql_query = "";

    if("RawDataOutBoundweekly".equalsIgnoreCase(jobName)){
        log.info("=========RawDataOutBoundweekly=========");

        sql_query = "select * from vw_rawdata_weekly";

    }else if("RawDataOutBoundmonthly".equalsIgnoreCase(jobName)){
        log.info("================RawDataOutBoundmonthly=============");

        sql_query = "select * from vw_rawdata_monthly";
    }
    log.info("ENTERING rawDataDBReader  ===================");


    JdbcCursorItemReader<RawDataExtractionDTO> datareader = new 
    JdbcCursorItemReader<>();
    datareader.setSql(sql_query);
    datareader.setDataSource(dataSource);
    datareader.setRowMapper(new BeanPropertyRowMapper<>
    (RawDataExtractionDTO.class));
    return datareader;
}

no error throw, but if i put debug point after my reader it wont go to my processor at all, it just shutdown the job.

Upvotes: 1

Views: 3584

Answers (1)

Niraj Sonawane
Niraj Sonawane

Reputation: 11115

You can implement FlatFileHeaderCallback to write header of file.

http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/item/file/FlatFileHeaderCallback.html

Some sample code to configure FlatFileHeaderCallback. Even reader does not read any record FlatFileHeaderCallback will be called and will write header. final file will have header only

@Bean
    public FlatFileItemWriter<Person> myWriter()
    {
        System.out.println("FlatFileItemWriter*******************");
        FlatFileItemWriter<Person> writer = new FlatFileItemWriter<Person>();
        writer.setResource(new FileSystemResource("output.csv"));
        DelimitedLineAggregator<Person> delLineAgg = new DelimitedLineAggregator<Person>();
        delLineAgg.setDelimiter(",");
        BeanWrapperFieldExtractor<Person> fieldExtractor = new BeanWrapperFieldExtractor<Person>();
        fieldExtractor.setNames(new String[] {"firstName", "lastName"});
        delLineAgg.setFieldExtractor(fieldExtractor);
        writer.setLineAggregator(delLineAgg);

   writer.setHeaderCallback(myFlatFileHeaderCallback);      


        return writer;
    }


@Component
public class MyFlatFileHeaderCallback implements FlatFileHeaderCallback {

    @Override
    public void writeHeader(Writer writer) throws IOException {
        System.out.println("Header called");

    }

}

Upvotes: 3

Related Questions