Spring Batch MultiResourceItemWriter: How to uniquely identify each of the written files
Use MultiResourceItemWriter to write multiple CSV files in one step. After writing various files in Step, I would like to be able to email these files to the appropriate recipients using StepExecutionListener.
But the question is how do I know which files should be sent to which email? filename or suffix (I have a custom ResourceSuffixCreator, but it only gets an index and can’t efficiently identify a file from another.) )
Use Spring Boot 2.2.7
Thanks for your help.
Update
For example, I have steps in this job. The success step uses MultiResourceItemWriter to output success-related files for each email destination.
return this.stepBuilderFactory.get("generateSuccessRecords")
.<SuccessReport, SuccessReport>chunk(1)
.reader(successReportItemReader(null, null))
.processor(itemProcessor)
.writer(successReportItemWriter(null))
.build();
successReportItemWriter is a delegate to a MultiResourceItemWriter
return new MultiResourceItemWriterBuilder<SuccessReport>()
.name("successReportItemWriter")
.itemCountLimitPerResource(1)
.delegate(individualSuccessReportItemWriter())
.resource(new FileSystemResource(jobReportDirectory + "/successReport"))
.resourceSuffixCreator(suffixCreator)
.build();
individualSuccessReportItemWriter() is as follows.
FlatFileItemWriter<SuccessReport> itemWriter = new FlatFileItemWriter<>();
itemWriter.setName("individualSuccessReportItemWriter");
itemWriter.setHeaderCallback(new SuccesssReportHeaderCallback());
itemWriter.setLineAggregator(new SuccessReportLineAggregator());
After the Success step generates a SuccessReport, the Fallout step queries the database and repeats the operation, again using MultiResourceItemWriter to create a FalloutReport .csv file for each email destination.
The goal is to be able to email success reports and Fallout Report .csv files to each email as attachments. Let’s say there are 25 email destinations. Running 2 steps (success and failure) will result in 25 successful . CSV file and 25 failed . CSV file. Each email destination will get 1 success and 1 fallout .csv file as an attachment.
The SuccessReport and FalloutReport classes have an email destination when generating .csv files – but you can’t name the files that way because the suffix Creator doesn’t allow you to name them accordingly.
Solution
I
came up with a hack that I find a bit rough, but hopefully it will help. From your sample code, it appears that you are using a block size of 1, and each List
element uses a separate output file (corresponding to your description of one target email for each report). In this case, the following advice seems safe enough.
If your I don’t know what the class hierarchy looks like for these two report types, so you need to use two different classes for each report type, or a class for the parent type with email destination data. You also need to make sure that this I hope this works for you or gives you alternative ideas to solve the problem.ResourceSuffixCreator
It is also a public class SuccessReportSuffixCreator
implements ItemWriteListener<SuccessReport>, ResourceSuffixCreator {
private String emailTarget = "";
@Override
public String getSuffix( int i ) {
return Md5Crypt.md5Crypt( this.emailTarget.getBytes() ) + "." + i + ".csv";
}
@Override
public void beforeWrite( List<? extends SuccessReport> list ) {
this.emailTarget = list.get( 0 ).getEmailTarget();
}
@Override
public void afterWrite( List<? extends SuccessReport> list ) {
clear emailTarget?
}
@Override
public void onWriteError( Exception e, List<? extends SuccessReport> list ) {
clear emailTarget?
}
}
ItemWriteListener
is registered on Step
so that its event handler is called correctly.