У меня есть заголовок, который выглядит так:
// Writer
@Bean(name = "cms200Writer")
@StepScope
public FlatFileItemWriter<Cms200Item> cmsWriter(@Value("#{jobExecutionContext}") Map<Object, Object> ec, //
@Qualifier("cms200LineAggregator") FormatterLineAggregator<Cms200Item> lineAgg) throws IOException {
@SuppressWarnings("unchecked")
String fileName = ((Map<String, MccFtpFile>) ec.get(AbstractSetupTasklet.BATCH_FTP_FILES)).get("cms").getLocalFile();
//Ensure the file can exist.
PrintWriter fos = getIoHarness().getFileOutputStream(fileName);
fos.close();
FlatFileItemWriter<Cms200Item> writer = new FlatFileItemWriter<>();
writer.setResource(new FileSystemResource(fileName));
writer.setLineAggregator(lineAgg);
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
String formattedDate=dateFormat.format(date);
writer.setHeaderCallback(new FlatFileHeaderCallback() {
public void writeHeader(Writer writer) throws IOException {
writer.write(" Test Company. " + formattedDate);
writer.write("\n CMS200 CUSTOMER SHIPMENT MANIFEST AUTHORIZATION BY CUSTOMER NAME Page 1");
writer.write("\n\n");
writer.write(" CUSTOMER NAME CITY ST CONTROL MNFST ID AUTH CODE I03 CLS EDI EXPRESS POV MOST CURRENT DEACTIVE");
writer.write("\n");
writer.write(" NBR TRL 214 WORK ACCESS DATE ");
}
});
return writer;
}
Я хочу печатать этот заголовок каждый раз, когда обрабатывается 53 записи. Я не могу понять, как реализовать эту логику в моем задании Spring Batch. У меня есть writeCount, добавленный в мой контекст выполнения, но я не уверен, как получить к нему доступ здесь, или если это правильный подход.
Писатель, который я опубликовал, находится в моем файле BatchConfiguration.java.
Обновлено:
Ниже у меня есть свой файл и добавлен размер куска
@Bean(name = "cms200FileStep")
public Step createFileStep(StepBuilderFactory stepFactory, //
@Qualifier("cms200Reader") ItemReader<Cms200Item> reader, //
Cms200Processor processor, //
@Qualifier("cms200Writer") ItemWriter<Cms200Item> writer) {
return stepFactory.get("cms200FileStep") //
.<Cms200Item, Cms200Item>chunk(100000) //
.reader(reader) //
.processor(processor) //
.writer(writer).chunk(53) //
.allowStartIfComplete(true)//
.build();//
}
Обновлено: добавлена конфигурация задания
// Job
@Bean(name = "mccCMSCLRPTjob")
public Job mccCmsclrptjob(JobBuilderFactory jobFactory, //
@Qualifier("cms200SetupStep") Step setupStep, //
@Qualifier("cms200FileStep") Step fileStep, //
@Qualifier("putFtpFilesStep") Step putFtpStep, //
@Qualifier("cms200TeardownStep") Step teardownStep, //
@Autowired SingleInstanceListener listener,
@Autowired ChunkSizeListener chunkListener) { //
return jobFactory.get("mccCMSCLRPTjob") //
.incrementer(new RunIdIncrementer()) //
.listener(listener) //
.start(setupStep) //
.next(fileStep) //
.next(putFtpStep) //
.next(teardownStep) //
.build();
}
Редактировать: добавление слушателя
@Bean(name = "cms200FileStep")
public Step createFileStep(StepBuilderFactory stepFactory, //
@Qualifier("cms200Reader") ItemReader<Cms200Item> reader, //
Cms200Processor processor, //
@Qualifier("cms200Writer") ItemWriter<Cms200Item> writer,
@Autowired ChunkSizeListener listener) {
return stepFactory.get("cms200FileStep") //
.<Cms200Item, Cms200Item>chunk(100000) //
.reader(reader) //
.processor(processor) //
.writer(writer).chunk(53) //
.allowStartIfComplete(true)//
.listener(listener) //
.build();//
}
Обновлено: После долгих поисков вот где я
// Utility Methods
@Bean(name = "cms200FileStep")
public Step createFileStep(StepBuilderFactory stepFactory, Map<Object, Object> ec, //
@Qualifier("cms200Reader") ItemReader<Cms200Item> reader, //
Cms200Processor processor, //
@Qualifier("cms200Writer") ItemWriter<Cms200Item> writer) throws IOException {
@SuppressWarnings("unchecked")
String fileName = ((Map<String, MccFtpFile>) ec.get(AbstractSetupTasklet.BATCH_FTP_FILES)).get("cms").getLocalFile();
return stepFactory.get("cms200FileStep") //
.<Cms200Item, Cms200Item>chunk(100000) //
.reader(reader) //
.processor(processor) //
.writer(writer).chunk(53) //
.allowStartIfComplete(true)//
// .listener((ChunkListener) listener) //
.listener((ChunkListener) new ChunkSizeListener(new File(fileName))) //
.build();//
}
Я могу попробовать - я обновил свой исходный пост, чтобы показать всего моего автора. Будет ли это работать?
FlatFileHeaderCallback вызывается только один раз перед этапом, ориентированным на фрагменты, то есть перед всеми фрагментами.
I want to print this header everytime 53 records are processed
Что вы можете сделать, так это установить размер фрагмента на 53 и использовать ChunkListener или ItemWriteListener для записи необходимых данных.
Обновлено: добавить пример
class MyChunkListener extends StepListenerSupport {
private FileWriter fileWriter;
public MyChunkListener(File file) throws IOException {
this.fileWriter = new FileWriter(file, true);
}
@Override
public void beforeChunk(ChunkContext context) {
try {
fileWriter.write("your custom header");
fileWriter.flush();
} catch (IOException e) {
System.err.println("Unable to write header to file");
}
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
try {
fileWriter.close();
} catch (IOException e) {
System.err.println("Unable to close writer");
}
return super.afterStep(stepExecution);
}
}
Комментарии не для расширенного обсуждения; этот разговор был перешел в чат.
Попробуйте вызвать метод writeHeader в afterStep() с проверкой writeCount(). Но я предполагаю, что это можно сделать только после обработки всех строк. Или, может быть, вы можете разделить первые 53 записи как отдельную задачу в StepExecution.