【问题标题】:how to get readSkipCount from Step Execution in itemProcessor/itemWriter?如何从 itemProcessor/itemWriter 中的 Step Execution 获取 readSkipCount?
【发布时间】:2021-07-29 06:04:10
【问题描述】:

我目前正在将带有 spring 批处理的 csv 文件读取到我必须保存当前文件的总行以及拒绝/跳过的行的对象中,并且使用 StepExecutionListener 不起作用,因为我需要在步骤结束之前获取它并且不后步。有没有办法让它们保存在 itemProcessor 或 itemWriter 中而无需添加其他步骤?

【问题讨论】:

    标签: spring spring-batch


    【解决方案1】:

    我需要在步骤结束之前而不是在步骤之后获取它

    直到步骤结束(即读取整个文件),您无法获得总行数。

    使用 StepExecutionListener 不起作用

    使用步骤执行侦听器是可行的方法。你没有分享你的代码来看看为什么这对你不起作用,但这里有一个简单的例子:

    import java.util.Arrays;
    
    import org.springframework.batch.core.ExitStatus;
    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.JobParameters;
    import org.springframework.batch.core.StepExecution;
    import org.springframework.batch.core.StepExecutionListener;
    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.launch.JobLauncher;
    import org.springframework.batch.item.ItemProcessor;
    import org.springframework.batch.item.support.ListItemReader;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @EnableBatchProcessing
    public class MyJobConfiguration {
    
        @Bean
        public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
            return jobs.get("myJob")
                    .start(steps.get("myStep")
                            .<Integer, Integer>chunk(2)
                            .reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4)))
                            .processor((ItemProcessor<Integer, Integer>) item -> {
                                if (item % 2 != 0) {
                                    throw new Exception("No odd numbers here!");
                                }
                                return item;
                            })
                            .writer(items -> items.forEach(System.out::println))
                            .faultTolerant()
                            .skip(Exception.class)
                            .skipLimit(5)
                            .listener(new StepExecutionListener() {
                                @Override
                                public void beforeStep(StepExecution stepExecution) {
                                    System.out.println("Starting step " + stepExecution.getStepName());
                                }
    
                                @Override
                                public ExitStatus afterStep(StepExecution stepExecution) {
                                    System.out.println("Step "+ stepExecution.getStepName() + " is complete");
                                    System.out.println("read.count = " + stepExecution.getReadCount());
                                    System.out.println("write.count = " + stepExecution.getWriteCount());
                                    System.out.println("skip.count = " + stepExecution.getSkipCount());
                                    return stepExecution.getExitStatus();
                                }
                            })
                            .build())
                    .build();
        }
    
        public static void main(String[] args) throws Exception {
            ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfiguration.class);
            JobLauncher jobLauncher = context.getBean(JobLauncher.class);
            Job job = context.getBean(Job.class);
            jobLauncher.run(job, new JobParameters());
        }
    
    }
    

    打印出来:

    Starting step myStep
    2
    4
    Step myStep is complete
    read.count = 4
    write.count = 2
    skip.count = 2
    

    【讨论】:

    • 我能够阅读它们,但只有在步骤列表器中才能读取项目处理器中的总读取行和跳过的行
    • 是的,但这将是直到 current 块之前的 current 项总数(即部分累积)。为此,您可以在处理器中注入步骤执行,请参阅stackoverflow.com/questions/14949985/…
    • 如何在处理器类中注入它?
    • 使用@BeforeStep在读取任何块/项目之前提供信息我仍然无法获得我尝试@BeforeProcess的当前总读取行数,因为我认为在处理之前获取它是合乎逻辑的但是显然我错了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-20
    相关资源
    最近更新 更多