Заголовок файла Spring Batch

У меня есть заголовок, который выглядит так:

// 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();//
    }

Попробуйте вызвать метод writeHeader в afterStep() с проверкой writeCount(). Но я предполагаю, что это можно сделать только после обработки всех строк. Или, может быть, вы можете разделить первые 53 записи как отдельную задачу в StepExecution.

Mebin Joe 11.03.2019 14:06

Я могу попробовать - я обновил свой исходный пост, чтобы показать всего моего автора. Будет ли это работать?

Josh 11.03.2019 14:14
0
2
1 258
1

Ответы 1

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);
    }
}

Комментарии не для расширенного обсуждения; этот разговор был перешел в чат.

Bhargav Rao 13.03.2019 20:24

Другие вопросы по теме