Spring 将失败的步骤添加到执行上下文的步骤侦听器

Spring 将失败的步骤添加到执行上下文的步骤侦听器,spring,spring-batch,listener,Spring,Spring Batch,Listener,我想知道是否有一种方法可以使用afterStep并创建一个步骤执行侦听器来检查作业中的任何失败步骤,并将该步骤名称和退出状态添加到执行上下文中 虽然我的作业中的一个步骤失败,但我们返回RepeatStatus.FINISHED。我创建了一个电子邮件报告,并希望包括失败的步骤名称和状态。这是我的电子邮件任务 public class SendEmailTasklet implements Tasklet { final static Logger LOGGER = LoggerFacto

我想知道是否有一种方法可以使用afterStep并创建一个步骤执行侦听器来检查作业中的任何失败步骤,并将该步骤名称和退出状态添加到执行上下文中

虽然我的作业中的一个步骤失败,但我们返回
RepeatStatus.FINISHED
。我创建了一个电子邮件报告,并希望包括失败的步骤名称和状态。这是我的电子邮件任务

public class SendEmailTasklet implements Tasklet {

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

    @Autowired
    public JavaMailSender emailSender;

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

        JobParameters jobParameters = chunkContext.getStepContext().getStepExecution().getJobParameters();
        ExecutionContext ec = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();

        //obtain email address and program name from the execution context
        String programName = ec.getString(AbstractSetupTasklet.BATCH_PROGRAM_NAME);
        String toEmail = jobParameters.getString("TOEMAIL");

        if(StringUtils.isEmpty(toEmail)) {

            LOGGER.info("No email address associated with the user. Job status is " + programStatus);

            return RepeatStatus.FINISHED;
        }
        else {

            //construct the message
            SimpleMailMessage message = new SimpleMailMessage();
            message.setTo(toEmail);
            message.setSubject("Batch Reporting");
            message.setText("The batch program " + programName + " has exited with a status of " + programStatus);
            emailSender.send(message);

            LOGGER.info("Email succesfully sent to user at " + toEmail);

            return RepeatStatus.FINISHED;
        }
    }


}
从上面的代码中可以看出,我想返回
程序状态
,或者说“作业在X步骤失败,状态为X”

编辑:

对于任何想知道的人,我将在下面发布我完成的代码。我提出了一种新方法来构造电子邮件消息,以减少重复代码

public class SendEmailTasklet implements Tasklet {

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

    @Autowired
    public JavaMailSender emailSender;

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

        //Get the job info
        JobParameters jobParameters = chunkContext.getStepContext().getStepExecution().getJobParameters();
        ExecutionContext ec = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();

        //Get the step info
        JobExecution jobExecutions = chunkContext.getStepContext().getStepExecution().getJobExecution();
        Collection<StepExecution> stepExecution = jobExecutions.getStepExecutions();

        //Get the email address and program name
        String programName = ec.getString(AbstractSetupTasklet.BATCH_PROGRAM_NAME);
        String toEmail = jobParameters.getString("TOEMAIL");


        //If no email address exists, do not send the email.
        if(StringUtils.isEmpty(toEmail)) {

            LOGGER.info("No email address associated with the user.");
            return RepeatStatus.FINISHED;

        }
        else {

            //Check for the first failed step
            for (StepExecution step : stepExecution) {
                if(step.getExitStatus().equals(ExitStatus.FAILED)) {
                    String failedStep = step.getStepName();
                    sendBatchReportEmail(toEmail, programName, failedStep);
                    LOGGER.info(programName + " has failed on the step " + failedStep);
                    break;
                }
            }
            sendBatchReportEmail(toEmail, programName, null);
            LOGGER.info("No email address associated with the user.");
            return RepeatStatus.FINISHED;
        }

    }

    public void sendBatchReportEmail(String toEmail, String programName, String stepName) {
        if(Utils.isEmpty(stepName)) {
            //construct the message
            SimpleMailMessage message = new SimpleMailMessage();
            message.setTo(toEmail);
            message.setSubject("Batch Reporting");
            message.setText("The batch program " + programName + " has completed.");
            emailSender.send(message);
            LOGGER.info("Email succesfully sent to user at " + toEmail);            
        }
        else {
          //construct the message
            SimpleMailMessage message = new SimpleMailMessage();
            message.setTo(toEmail);
            message.setSubject("Batch Reporting");
            message.setText("The batch program " + programName + " has failed on step: " + stepName);
            emailSender.send(message);
            LOGGER.info("Email succesfully sent to user at " + toEmail + "and has failed on the step: " + stepName);
        }

    }

}
公共类SendEmailTasklet实现Tasklet{
最终静态记录器Logger=LoggerFactory.getLogger(sendmailtasklet.class);
@自动连线
公共JavaMailSender电子邮件发件人;
@凌驾
public RepeatStatus execute(StepContribution贡献,ChunkContext ChunkContext)引发异常{
//获取工作信息
JobParameters JobParameters=chunkContext.getStepContext().getStepExecution().getJobParameters();
ExecutionContext ec=chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();
//获取步骤信息
JobExecution jobExecutions=chunkContext.getStepContext().getStepExecution().getJobExecution();
Collection stepExecution=jobExecutions.getStepExecutions();
//获取电子邮件地址和程序名称
String programName=ec.getString(AbstractSetupTasklet.BATCH\u程序名称);
String toEmail=jobParameters.getString(“toEmail”);
//如果没有电子邮件地址,请不要发送电子邮件。
如果(StringUtils.isEmpty(toEmail)){
LOGGER.info(“没有与用户关联的电子邮件地址”);
返回RepeatStatus.FINISHED;
}
否则{
//检查第一个失败的步骤
for(步骤执行步骤:步骤执行){
if(step.getExitStatus().equals(ExitStatus.FAILED)){
字符串failedStep=step.getStepName();
sendBatchReportEmail(toEmail、programName、failedStep);
LOGGER.info(programName+”在步骤“+failedStep”上失败);
打破
}
}
sendBatchReportEmail(toEmail,程序名,空);
LOGGER.info(“没有与用户关联的电子邮件地址”);
返回RepeatStatus.FINISHED;
}
}
public void sendBatchReportEmail(String-toEmail、String-programName、String-stepName){
if(Utils.isEmpty(步骤名称)){
//构建消息
SimpleEmailMessage=新建SimpleEmailMessage();
message.setTo(toEmail);
message.setSubject(“批量报告”);
message.setText(“批处理程序”+programName+“已完成”);
emailSender.send(message);
LOGGER.info(“通过“+toEmail”成功发送给用户的电子邮件);
}
否则{
//构建消息
SimpleEmailMessage=新建SimpleEmailMessage();
message.setTo(toEmail);
message.setSubject(“批量报告”);
message.setText(“批处理程序”+programName+”在步骤“+stepName”上失败);
emailSender.send(message);
LOGGER.info(“电子邮件已成功发送至“+toEmail+”处的用户,但在步骤“+stepName”上失败);
}
}
}

您可以通过
chunkContext.getStepContext().getstepcexecution().getJobExecution()
从区块上下文访问作业执行

一旦执行了作业,就可以使用
jobsecution.getStepExecutions()
获取所有步骤执行,并对它们进行迭代以检查最后失败的步骤

上次失败的StepExecution为您提供了创建消息所需的步骤名称、退出代码和描述,然后将其添加到作业执行上下文中


希望这有帮助。

太棒了,非常感谢。我来看看我能用它做些什么我已经用下面的代码获得了所有的步骤执行
Collection stepExecution=jobExecutions.getStepExecutions()
您认为检查最后一步失败的最佳方法是什么?您可以选择第一步,即
ExitStatus=failed