如何使ServletContextListener停止Java EE应用程序?

Fre*_*eit 10 servlets java-ee servlet-listeners

我有一个ServletContextListener,它在我的Java EE应用程序启动时执行一些数据库管理功能.这在JPA和应用程序的其他部分启动/加载之前在我的应用程序中运行.如果数据库维护失败,我将记录错误.如果数据库维护失败,应用程序将无法正常运行,我想暂停应用程序.

如何从ServletContextListener.contextInitialized中优雅正确地停止应用程序?

Viven给出的解决方案很接近,但并不完全.当我抛出RuntimeException时,Glassfish处于不一致的状态,其管理控制台无法访问,但某些进程仍在运行并保持端口3700(IIOP?)打开,从而阻止重启.

Viv*_*sse 5

如果您ServletContextListener抛出异常,则webapp将无法正确加载,并且应用程序服务器可能会阻止所有后续请求(并以500错误响应).

它并不完全阻止应用程序启动,也不会停止应用程序,但它会阻止应用程序的任何进一步使用,并且可能对您的情况有用.

在规范中进行适当验证后,此行为在规范中不是必需的.该服务器可以(不是必须)返回500错误.因此,必须小心使用该解决方案.

有关Servlet规范的引用,请参阅此答案.

  • 抛出`RuntimeException`不会停止app服务器.****可以**阻止应用程序启动,**可能**以500(服务器错误)响应代码响应所有后续的应用程序请求.使用`System.exit`是一个非常糟糕的主意.即使其他(完美工作)应用程序部署在同一台服务器上,它也会强制关闭服务器.我曾经处理过这样做的应用程序(Alfresco),相信我,这不仅仅是烦人的! (5认同)
  • "如果你的ServletContextListener抛出异常,webapp将无法正确加载" - 你怎么知道这个?规范没有定义这样的东西.任何给定的应用服务器都可能只报告异常,并且无论如何都会继续.`ServletContextListener`不是为了影响应用程序的生命周期而设计的. (2认同)
  • 第11.6段描述了"听众例外". - "容器可以使用HTTP状态代码500响应对Web应用程序的所有后续请求,以指示应用程序错误." (2认同)

ksc*_*eid 5

在您的侦听器中,捕获所有异常并使用servlet上下文属性存储有关错误的标志或其他有用信息。您可能还应该记录一些内容,以指示该应用程序无法正常运行。

此时,您的选择可能取决于应用程序的体系结构。如果所有请求均由单个控制器/调度程序Servlet处理,则让其init方法检查上下文属性并抛出可能是有意义的UnavailableException。请注意,该异常仅适用于抛出该异常的特定servlet。如果您的应用程序包含许多servlet或允许直接访问其他资源,则这将使方法的管理难度降低。

另一个选择是创建一个过滤器来拦截每个请求,检查上下文属性,然后引发异常。当然可以有其他变化。