I am using Spring Batch to write multiple reports. Requirement is i will get records with BranchId and name. I need to create one file for each branchId and write respective data into that file along with some header and footer.
Example:
Student A = new Student("A",1);
Student B = new Student("B",2);
Student C = new Student("C",1);
Student D = new Student("D",4);
In this case it should create total 3 files
file1-->1.txt(with A,C)
file2-->2.txt(with B)
file3-->4.txt(with D))
.
I am using ClassifierCompositeItemWriter to create / reuse the FlatFileItemWriter based on data(id in this case) & able to create the files successfully. For header and footer - using callbacks at writer level. Generated files are having only HEADER and DATA. But somehow FOOTER is not at all getting executed.
Looks like some issues with File closing before Footer or issue with usage of STEP SCOPE.
Can someone help me in getting the FOOTER called.
here is the code.
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
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.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.DelimitedLineAggregator;
import org.springframework.batch.item.support.ClassifierCompositeItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.classify.Classifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
@Configuration
@EnableBatchProcessing
public class MyJob3 {
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJob3.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job").start(steps.get("step").<Student, Student>chunk(5)
.reader(itemReader())
.writer(getStudentItemWriter(itemWriterClassifier()))
.build())
.build();
}
@Bean
@StepScope
public ItemReader<Student> itemReader() {
Student A = new Student("A", 1);
Student B = new Student("B", 2);
Student C = new Student("C", 1);
Student D = new Student("D", 4);
Student E = new Student("E", 4);
return new ListItemReader<>(Arrays.asList(A,B,C,D,E));
}
Map<Integer, FlatFileItemWriter<Student>> map = new HashMap<>();
@Bean
@StepScope
public ClassifierCompositeItemWriter<Student> getStudentItemWriter(Classifier<Student, ItemWriter<? super Student>> classifier) {
ClassifierCompositeItemWriter<Student> compositeItemWriter = new ClassifierCompositeItemWriter<>();
compositeItemWriter.setClassifier(classifier);
return compositeItemWriter;
}
@Bean
@StepScope
public Classifier<Student, ItemWriter<? super Student>> itemWriterClassifier() {
return student -> {
System.out.println("Branch Id ::" + student.getBranchId() + " and Student Name" + student.getName());
if (map.containsKey(student.getBranchId())) {
FlatFileItemWriter<Student> result = map.get(student.getBranchId());
System.out.println("Exising Writer object ::" + result);
return result;
}
String fileName ="Branch_Info_" + student.getBranchId() + ".txt";
BeanWrapperFieldExtractor<Student> fieldExtractor = new BeanWrapperFieldExtractor<>();
fieldExtractor.setNames(new String[] { "branchId", "name" });
DelimitedLineAggregator<Student> lineAggregator = new DelimitedLineAggregator<>();
lineAggregator.setFieldExtractor(fieldExtractor);
FlatFileItemWriter<Student> flatFileItemWriter = new FlatFileItemWriter<>();
flatFileItemWriter.setResource(new FileSystemResource(fileName));
flatFileItemWriter.setAppendAllowed(true);
flatFileItemWriter.setLineAggregator(lineAggregator);
System.out.println("Writing header...");
flatFileItemWriter.setHeaderCallback(writer -> writer.write("Header"));
System.out.println("Writing Footer...");
flatFileItemWriter.setFooterCallback(writer -> writer.write("Footer"));
System.out.println("Writing done...");
flatFileItemWriter.open(new ExecutionContext());
map.put(student.getBranchId(), flatFileItemWriter);
System.out.println("New Writer object ::" + flatFileItemWriter);
return flatFileItemWriter;
};
}
}