簡體   English   中英

Spring-Batch:如何在Spring Batch中使用skip方法捕獲異常消息?

[英]Spring-batch : How to catch exception message with skip method in spring batch?

我是Spring Batch的新手。 我的問題是如何在spring-batch中使用skip方法捕獲異常? 據我所知,當spring批處理中發生某些異常時,我們可以使用skip方法跳過它們。 但是,如何使用skip方法獲取異常消息? 有人建議我使用SkipListener ,該類具有三個回調方法,如onSkipInProcess() ,但對我來說沒有用。 而且ItemProcessListener也不起作用。

如下代碼:(我使用skip方法忽略異常,並使用兩個偵聽器接收異常信息)

Step mainStep = stepBuilder.get("run")
        .<ItemProcessing, ItemProcessing>chunk(5)
        .faultTolerant()
        .skip(IOException.class).skip(SocketTimeoutException.class)//skip IOException here
        .skipLimit(2000)
        .reader(reader)
        .processor(processor)
        .writer(writer)
        .listener(stepExecListener)
        .listener(new ItemProcessorListener()) //add process listener
        .listener(new SkipExceptionListener()) //add skip exception listner
        .build();

ItemProcessorListener如下所示:

//(this class implements ItemProcessListener )
{
    @Override
    public void beforeProcess(Object item) {
        // TODO Auto-generated method stub

    }
    @Override
    public void afterProcess(Object item, Object result) {
        logger.info("invoke remote finished, item={},result={}",item,result);

    }
    @Override
    public void onProcessError(Object item, Exception e) {
        logger.error("invoke remote error, item={},exception={},{}",item,e.getMessage(),e);
    }
}

SkipExceptionListener如下所示:

//(implements SkipListener<Object, Object>)
{

    @Override
    public void onSkipInRead(Throwable t) {
        // TODO Auto-generated method stub      
    }

    @Override
    public void onSkipInWrite(Object item, Throwable t) {
        // TODO Auto-generated method stub      
    }

    @Override
    public void onSkipInProcess(Object item, Throwable t) {
        logger.info("invoke remote finished,item={},itemJsonStr={},errMsg={},e={}",
                    item,
                    JSONObject.toJSONString(item),
                    t.getMessage(),
                    t);
    }
}

問題是所有記錄器均不起作用。 實際上,跳過方法效果很好,我可以在表batch_step_execution中獲取跳過計數。 我不確定這兩個偵聽器是否要回調。 誰能告訴我該怎么辦? 還是還有什么? 非常感謝。

我也無法通過實現SkipListener來使其工作(很高興知道為什么),但是最后我使用了注釋方法,該注釋方法在文檔中僅作了簡要介紹。 同樣,有人在這里使用實現方法( 問題 )遇到了類似的問題,答案中的人使用了這種注釋方法而不是實現接口。

示例bean:

@Component
public class CustomSkippedListener {

    @OnSkipInRead
    public void onSkipInRead(Throwable throwable) {
    }

    @OnSkipInWrite
    public void onSkipInWrite(FooWritingDTO fooWritingDTO, Throwable throwable) {
        LOGGER.info("balabla" + throwable.getMessage());
    }

    @OnSkipInProcess
    public void onSkipInProcess(FooLoaderDTO fooLoaderDTO, Throwable throwable) {
        LOGGER.info("blabla"  + throwable.getMessage());
    }

    private static final Logger LOGGER = LoggerFactory.getLogger(CustomSkippedListener.class);


}

然后自動連線並像您一樣將其包含在步驟鏈中。

如何在Spring Batch中使用skip方法捕獲異常消息?

您可以通過實現SkipListener接口或擴展SkipListenerSupport類來實現。 SkipListener界面中的所有方法都具有Throwable參數,該參數是引發的異常,導致該項目被跳過。 在這里您可以獲取異常消息。 這是一個例子:

import java.util.Arrays;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.SkipListener;
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;

@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 items -> {
            for (Integer item : items) {
                System.out.println("item = " + item);
            }
        };
    }

    @Bean
    public ItemProcessor<Integer, Integer> itemProcessor() {
        return item -> {
            if (item.equals(7)) {
                throw new IllegalArgumentException("Sevens are not accepted!!");
            }
            return item;
        };
    }

    @Bean
    public Step step() {
        return steps.get("step")
                .<Integer, Integer>chunk(5)
                .reader(itemReader())
                .processor(itemProcessor())
                .writer(itemWriter())
                .faultTolerant()
                .skip(IllegalArgumentException.class)
                .skipLimit(3)
                .listener(new MySkipListener())
                .build();
    }

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

    public static class MySkipListener implements SkipListener<Integer, Integer> {

        @Override
        public void onSkipInRead(Throwable t) {

        }

        @Override
        public void onSkipInWrite(Integer item, Throwable t) {

        }

        @Override
        public void onSkipInProcess(Integer item, Throwable t) {
            System.out.println("Item " + item + " was skipped due to: " + t.getMessage());
        }
    }

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

}

在此示例中, MySkipListener實現了SkipListener並在嘗試執行操作時從異常中獲取消息。 該示例讀取從1到10的數字,並跳過數字7。您可以運行main方法,並應看到以下輸出:

item = 1
item = 2
item = 3
item = 4
item = 5
item = 6
item = 8
item = 9
item = 10
Item 7 was skipped due to: Sevens are not accepted!!

我希望這有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM