【问题标题】:spring batch customize exit description春季批处理自定义退出说明
【发布时间】:2017-05-18 12:14:05
【问题描述】:

我们有一个通过方法调用执行的 spring 批处理作业,我们使用以下代码发送回作业的退出状态(如果发生错误):

          JobExecution jeStatus = jobExplorer.getJobExecution(je.getId());
          String exitDescription = jeStatus.getExitStatus().getExitDescription();
          return exitDescription;

它显示了传播异常的整个堆栈跟踪。 例如。, 我们的 ItemReader 正在抛出一些异常,该异常被处理并重新抛出以获取一些自定义消息:

     try {            
          //Some code here which fails validation         
     }catch(Exception e) {
         throw new Exception("File validation failed");       
     }

那么返回给客户端的消息是:

> causes:org.springframework.beans.factory.BeanCreationException: Error
> creating bean with name 'scopedTarget.prjItemReader' defined in class
> path resource [com/org/prjcore/config/ImportJobConfiguration.class]:
> Bean instantiation via factory method failed; nested exception is
> org.springframework.beans.BeanInstantiationException: Failed to
> instantiate [org.springframework.batch.item.xml.StaxEventItemReader]:
> Factory method 'prjItemReader' threw exception; nested exception is
> java.lang.Exception: File validation failed \r\n\tat
> org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)\r\n\tat
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1128)\r\n\tat
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1023)\r\n\tat
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)\r\n\tat
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)\r\n\tat
> org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:345)\r\n\tat
> org.springframework.batch.core.scope.StepScope.get(StepScope.java:113)\r\n\tat
> org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340)\r\n\tat
> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)\r\n\tat
> org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)\r\n\tat
> org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.getTarget(CglibAopProxy.java:687)\r\n\tat
> org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:637)\r\n\tat
> org.springframework.batch.item.xml.StaxEventItemReader$$EnhancerBySpringCGLIB$$c6888d6d.open()\r\n\tat
> org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:96)\r\n\tat
> org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:310)\r\n\tat
> org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:197)\r\n\tat
> org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)\r\n\tat
> org.springframework.batch.core.job"}

上面是一个字符串,它也作为退出描述存储在 job_execution_context 中,因此 spring batch 以相同的方式响应。

我需要给客户一个简洁的像样的消息,如“文件验证失败”。

但是,可以通过对当前退出描述进行字符串操作,是否有任何方法可以覆盖框架的这种行为,其中消息可以从异常中取出,而不是发送整个堆栈跟踪。任何指针将不胜感激。

【问题讨论】:

    标签: java spring-batch


    【解决方案1】:

    您可以注册一个StepExecutionListener 以执行您想要的操作。

    public class CustomStepExecutionListener implements StepExecutionListener {
    
        private static final String VALIDATION_FAILURE = "File validation failed";
    
        public ExitStatus afterStep(final StepExecution stepExecution) {
            ExitStatus exitStatus = stepExecution.getExitStatus();
            String exitCode = exitStatus.getExitCode();
            if (ExitStatus.FAILED.getExitCode().equals(exitCode)) {
                String exitDescription = exitStatus.getExitDescription();
                if (exitDescription.contains(VALIDATION_FAILURE)) {
                    return new ExitStatus(exitCode, VALIDATION_FAILURE);
                }
            }
            return null;
        }
    
        public void beforeStep(final StepExecution stepExecution) {
            //no-op
        }
    
    }
    

    【讨论】:

    • 感谢您的回复,我怎样才能获得对抛出异常的引用。我需要堆栈跟踪而不是字符串。我正在避免字符串操作,因为可能有 n 个错误。
    • 抱歉,您最初的问题并不清楚。如果是这种情况,只需使用stepExecution.getFailureExceptions()。它将提供所有抛出的列表。
    • 我在想我可以覆盖从堆栈跟踪创建字符串的方法。但是这种方法更简单而且更好。
    • 很高兴我能帮上忙!请将问题标记为已回答,以便其他人知道它已得到解决。
    猜你喜欢
    • 2014-12-15
    • 2018-05-27
    • 2015-05-13
    • 2017-06-25
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    相关资源
    最近更新 更多