[英]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.