java - Spring 批处理 - 跳过 MyException 停止所有其他异常

标签 java spring-batch

目标:如果存在 AdmisSkipException(自定义异常),我希望作业跳过记录并继续处理下一行。 如果有任何其他异常,我希望工作停止。

这是我到目前为止所拥有的:

session :

       .<Admis, PreCandidat>chunk(100)
       .reader(readerDBAdmis())
       .processor(new AdmisItemProcessor(preCandidatRepository, scolFormationSpecialisationRepository, preCandidatureRepository))
       .faultTolerant()
       .skipPolicy(AdmisVerificationSkipper())
       .writer(writerPGICocktail()).build();

AdmisSkipException:

public class AdmisSkipException extends Exception {
    private TypeRejet typeRejet;
    private Admis admis;

    public AdmisSkipException(TypeRejet typeRejet, Admis admis) {
        super();
        this.typeRejet = typeRejet;
        this.admis = admis;
    }

    public TypeRejet getTypeRejet() {
        return typeRejet;
    }

    public Admis getAdmis() {
        return admis;
    }
}

AdmisVerificationSkipper:

public class AdmisVerificationSkipper implements SkipPolicy {
    private AdmisRejetRepository admisRejetRepository;

    public AdmisVerificationSkipper(AdmisRejetRepository admisRejetRepository) {
        this.admisRejetRepository = admisRejetRepository;
    }

    @Override
    public boolean shouldSkip(Throwable exception, int skipCount) throws SkipLimitExceededException {
        if (exception instanceof AdmisSkipException) {
            AdmisSkipException admisSkipException = (AdmisSkipException) exception;
            AdmisRejet rejet = new AdmisRejet();
            rejet.setAdmis(admisSkipException.getAdmis());
            rejet.setTypeRejet(admisSkipException.getTypeRejet());
            admisRejetRepository.save(rejet);
            return true;
        }
        return false;
    }
}

使用此配置,如果 AdmisItemProcessor 中抛出 NullPointerException(例如),作业将继续而不是失败。 我应该改变什么来停止工作?

最佳答案

if there is an AdmisSkipException (custom exception) I want the job to skip the record and keep on processing next lines. If there is any other exception I want the job to stop.

您可以通过以下方式实现此目的:

   .<Admis, PreCandidat>chunk(100)
   .reader(readerDBAdmis())
   .processor(new AdmisItemProcessor(preCandidatRepository, scolFormationSpecialisationRepository, preCandidatureRepository))
   .writer(writerPGICocktail())
   .faultTolerant()
   .skip(AdmisSkipException.class)
   .skipLimit(SKIP_LIMIT) 
   .build();

查看您的代码,您可能必须创建自定义跳过策略,因为您想将跳过的项目保存在某处。我建议改用 SkipListener,它是专为此类需求而设计的。使用 shouldSkip 方法将项目保存到存储库是一个副作用。所以这最好由听众来完成。也就是说,您不需要自定义策略,.skip(AdmisSkipException.class).skipLimit(SKIP_LIMIT) 就足够了。

With this configuration, if a NullPointerException (for example) is thrown in AdmisItemProcessor, the job will continue instead of failing. What should I change to stop the job ?

这是一个示例,您可以运行它来查看它是如何工作的:

import java.util.Arrays;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
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.launch.JobLauncher;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Autowired;
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.lang.Nullable;

@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 ItemProcessor<Integer, Integer> itemProcessor() {
        return new ItemProcessor<Integer, Integer>() {
            @Nullable
            @Override
            public Integer process(Integer item) throws Exception {
                if (item.equals(3)) {
                    throw new IllegalArgumentException("No 3!");
                }
                if (item.equals(9)) {
                    throw new NullPointerException("Boom at 9!");
                }
                return item;
            }
        };
    }

    @Bean
    public ItemWriter<Integer> itemWriter() {
        return items -> {
            for (Integer item : items) {
                System.out.println("item = " + item);
            }
        };
    }

    @Bean
    public Step step() {
        return steps.get("step")
                .<Integer, Integer>chunk(1)
                .reader(itemReader())
                .processor(itemProcessor())
                .writer(itemWriter())
                .faultTolerant()
                .skip(IllegalArgumentException.class)
                .skipLimit(3)
                .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);
        JobExecution jobExecution = jobLauncher.run(job, new JobParameters());
        System.out.println(jobExecution);
    }

}

此示例在引发 IllegalArgumentException 时跳过项目,并在发生 NullPointerException 时使作业失败。

希望这有帮助。

关于java - Spring 批处理 - 跳过 MyException 停止所有其他异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52977386/

相关文章:

java - 不同上下文中同一类的变量

java - Websphere 应用程序级环境变量

java - Java 文件中 import 语句的含义

java - Spring 批处理 : SimpleJobRepository - Example not working

java - org.springframework.batch.item.ItemStreamException : Failed to initialize the reader on second api call

spring-batch - 如果 Spring Batch 出错,如何退出 tasklet?

spring - 将 Spring Security 与 Spring Batch 结合使用

Spring Batch从数据库读取一次,写入另一个数据库并写入CSV

java - 尝试测试 2 个 JSON 框架的性能 - 它看起来正确吗?

java - 在 Weblogic 9.2 上运行 Spring 应用程序时出现 ClassCastException