Spring异常处理程序-显示“ 500 javax.servlet.ServletException:Servlet.init()异常”的错误页面

时间:2018-10-25 09:23:27

标签: java spring

我的应用程序中有几个相互独立的Spring Services。在以@PostConstruct注释的服务的初始化方法中,将初始化对外部服务的某些依赖关系。但是,如果此初始化过程失败,则会显示错误消息,屏幕上显示消息500 javax.servlet.ServletException: Servlet.init() exception,其服务的BeanCreationException初始化的根本原因@PostConstruct无法成功执行。

我知道在Bean初始化失败的情况下,该应用程序将不再保持一致,因此整个应用程序可能无法按预期运行。但是,由于服务与应用程序的其余部分是独立的,因此我想捕获此初始化异常,并仍然以某种维护模式访问该应用程序,在这种情况下,如果服务的页面无法初始化,则会出现错误屏幕,应该被访问。

我尝试了使用带有@ControllerAdvice@ExceptionHandler方法注释的Global Controller Exception的几种方法,但是它们不会被触发。错误屏幕将立即显示。

另一种尝试是使用FilterHandlerExceptionResolver,但在这种情况下都不会被触发。

经过一些研究,我发现一些讨论表明此错误是致命的,因此无法处理或缓存。同样,在将请求传递给控制器​​句柄方法或任何已配置的过滤器之前,似乎引发了异常,因此也不会触发控制器异常处理程序。

现在我的问题是:为了处理BeanCreationExceptions,我还缺少其他方法吗?最终的解决方案应该以某种维护模式启动应用程序,当需要访问失败的Bean / Service时,它将提供一个错误屏幕,或者提供有关失败的初始化服务的信息。

在此先感谢任何有提示或进一步解释的人。

1 个答案:

答案 0 :(得分:0)

我发现了一些变通办法,可能会帮助其他面临相同问题的人,所以我想分享我的方法。

我最终使用了@Conditional批注(用于管理bean的创建)和在web.xml中配置的客户错误页面的组合。

基本上,我在取决于外部资源的每项服务上都使用@Conditional。条件检查是否可以初始化任何需要的外部依赖项。 如果Condition的matches方法返回true,则将创建用我的Condition类注释的服务,否则spring将忽略该服务的bean创建。

这是我的Condition实现的一个示例(我只是在matches中执行服务的@PostConstruct init方法中包含的内容)

public class ModuleCondition implements Condition {

   @Override
   public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) {
    if (/*check external dependencies*/)
       return true;
    else
       return false;
  }
}

这是使用条件的示例:

@Service
@Conditional(value = ModuleCondition.class)
public class MyService {
     ...
}

为了在无法初始化服务接口的情况下处理404错误,我使用了一个客户错误页面和一个CustomerErrorController。 (我遵循了以下教程here

因此,如果由于外部资源初始化失败而导致服务无法初始化,则会将用户转发到客户错误页面,通知用户当前所访问的模块不可用。