Доступ к значениям ExecutionContext в FooterCallBack с помощью пакета Spring - PullRequest
0 голосов
/ 25 октября 2019

Мне нужно присоединить ReadCount к нижнему колонтитулу файла, я не знаю, почему JobExecution в методе writeFooter имеет значение null.

Я нашел это и, согласно комментариям, я должен быть в состоянии записать эту информацию в нижний колонтитул: Доступ к значениям ExecutionContext в HeaderCallBack в Spring Batch

public class Footer implements FlatFileFooterCallback {

    private final String footer;
    private String julianDate;
    private StepExecution stepExecution;

    @AfterStep
    public void afterStep(StepExecution stepExecution) {
        ExecutionContext je = stepExecution.getJobExecution().getExecutionContext();
        je.putLong("writeCount", stepExecution.getReadCount());
    }

    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
    }

    // TODO: NEED TO REPLACE COUNT WITH NUMBER OF RECORDS IN FILE
    public Footer(){
        this.julianDate = createJulianDate();
        this.footer = "";
    }

    @Override
    public void writeFooter(Writer writer) throws IOException {
        JobExecution jobExecution = this.stepExecution.getJobExecution();
        ExecutionContext jobContext = jobExecution.getExecutionContext();
        writer.write(footer);
    }

Я попытался реализовать StepExecutionListener, и stepExecution является нулевым внутри метода writeFooter.

public class Footer implements FlatFileFooterCallback, StepExecutionListener {

    private final String footer;
    private String julianDate;
    private StepExecution stepExecution;

    // TODO: NEED TO REPLACE COUNT WITH NUMBER OF RECORDS IN FILE
    public Footer(){
        this.julianDate = createJulianDate();
        this.footer = "";
    }

    @Override
    public void beforeStep(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        System.out.println(stepExecution.getReadCount());
        System.out.println("END");
        return ExitStatus.COMPLETED;
    }

    @Override
    public void writeFooter(Writer writer) throws IOException {
        writer.write("Foot - number of items written: " + stepExecution.getWriteCount());
        writer.write(footer);
    }

1 Ответ

0 голосов
/ 28 октября 2019

Вы можете объявить обратный вызов нижнего колонтитула как bean-объект с шаговой областью и добавить счетчик записи из контекста выполнения шага, используя выражение SpEL. Вот пример:

import java.util.Arrays;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
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.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileFooterCallback;
import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder;
import org.springframework.batch.item.file.transform.PassThroughLineAggregator;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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 MyJob {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    public ItemReader<Integer> itemReader() {
        return new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
    }

    @Bean
    public ItemWriter<Integer> itemWriter() {
        return new FlatFileItemWriterBuilder<Integer>()
                .name("fileWriter")
                .resource(new FileSystemResource("numbers.txt"))
                .lineAggregator(new PassThroughLineAggregator<>())
                .footerCallback(footerCallback(null))
                .build();
    }

    @Bean
    @StepScope
    public FlatFileFooterCallback footerCallback(@Value("#{stepExecutionContext['fileWriter.written']}") Integer writeCount) {
        return writer -> writer.write("total items: " + writeCount);
    }

    @Bean
    public Step step() {
        return steps.get("step")
                .<Integer, Integer>chunk(5)
                .reader(itemReader())
                .writer(itemWriter())
                .build();
    }

    @Bean
    public Job job() {
        return jobs.get("job")
                .start(step())
                .build();
    }

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
    }

}

Это создает файл с именем numbers.txt со следующим содержанием:

1
2
3
4
5
6
7
8
9
10
total items: 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...