我正在使用带有OpenCSV的Spring Batch Tasklet来读取我的CSV文件 . 在提出问题之前,我知道块,但在后面的步骤中文件之间存在交叉验证,所以我必须继续使用Tasklet .
我要做的是报告丢失的文件或解析错误到我的报告步骤 . 我不确定应该向下一步报告失败的正确方法 . 我有以下代码 .
Initial step to read file.
public class CsvBatchReader<T> implements Tasklet, StepExecutionListener {
private final Logger logger = LoggerFactory.getLogger(CsvBatchReader.class);
private List batch;
private final Class<T> clazz;
private Path path;
public CsvBatchReader(Class<T> clazz, Path path) {
this.clazz = clazz;
this.path = path;
}
@Override
public void beforeStep(StepExecution stepExecution) {
logger.info("Reader initialized - " + clazz.getSimpleName());
batch = new ArrayList();
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
logger.info("Reader ended - " + clazz.getSimpleName());
return ExitStatus.COMPLETED;
}
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws UnexpectedJobExecutionException {
logger.info("Reader execute - " + clazz.getSimpleName());
ICsvToBean csvToBean = new CsvToBean(clazz, path);
try {
batch = csvToBean.readCsv();
} catch(IOException ex) {
// error message being caught from my csvToBean class.
throw new UnexpectedJobExecutionException("Invalid file " + ex.getMessage());
}
return RepeatStatus.FINISHED;
}
}
Reporting Step
我不确定如何传递异常消息或者是否有定义的方法来传递失败消息而不使用步骤执行上下文 .
public class CsvBatchReporting implements Tasklet, StepExecutionListener {
private final Logger logger = LoggerFactory.getLogger(CsvBatchCrossValidation.class);
private List errorMessages;
private List skippedInserts;
@Override
public void beforeStep(StepExecution stepExecution) {
logger.info("Reporting initialized");
ExecutionContext executionContext = stepExecution
.getJobExecution()
.getExecutionContext();
System.out.println("description " + stepExecution.getStatus());
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
logger.info("Reporting ended");
return ExitStatus.COMPLETED;
}
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
logger.info("Reporting execute");
//Email Error
return RepeatStatus.FINISHED;
}
}
Job Config
@Bean
public Job primaryCareJob(@Qualifier("reportingStep") Step reportingStep, @Qualifier("crossValidationStep") Step crossValidationStep) {
logger.info("Start PrimaryCare Job");
return jobs.get("primaryCareJob")
.start(readPrimaryCareStep()).on("FAILED").to(reportingStep)
.from(readPrimaryCareStep()).on("*").to(readPrimaryCareDetailStep())
.from(readPrimaryCareDetailStep()).on("FAILED").to(reportingStep)
.from(readPrimaryCareDetailStep()).on("*").to(processPrimaryCareStep())
.from(processPrimaryCareStep()).on("INVALID").to(reportingStep)
.from(processPrimaryCareStep()).on("*").to(processPrimaryCareDetailStep())
.from(processPrimaryCareDetailStep()).on("INVALID").to(reportingStep)
//Other steps
.from(reportingStep).on("*").end()
.from(reportingStep).on("*").fail()
.build()
.build();
}
我开始将我的作业模式更改为失败,而不是将其定义为无效,以使异常自动调用失败的步骤 . 我使用无效的其他步骤正在我的afterStep中使用以下代码定义 .
if(!errorMessages.isEmpty()) {
chunkContext.getStepContext().getStepExecution().setExitStatus(new ExitStatus("INVALID"));
}
如何将来自阅读器的CSV异常消息传递到我的报告步骤,以便我可以将其作为电子邮件发送?
3 回答
您可以访问作业执行的上一步中抛出的异常 . 这是一个例子:
此示例打印:
显然,您需要确保step1在所有情况下都流向step2(因此流程定义) .
希望这可以帮助 .
考虑使
errorMessages
成为一个bean:并将
errorMessages
注入两个tasklet .在
CsvBatchReader
tasklet中,检查execute(...)
抛出的任何异常,并根据需要更新errorMessages
:自
errorMessages
被注入CsvBatchReporting
,然后:虽然我原来的问题是关于将异常从一步传递到下一步,但我想指出一种使用
exitStatus
的替代方法 .在我的阅读器步骤中,我可以捕获我的csvToBean异常并创建一个类似的存在状态 .
然后我会在我的工作中创建条件流程 .
最后,在我的阅读器tasklet步骤中,我会像这样检索existStatus