停止从 ServletContextListener 方法 contextInitialized 启动 Web 应用程序

Stop launch of web app from `ServletContextListener` method `contextInitialized`

我已经实施了一个 ServletContextListener in a Java Servlet web app via the @WebListener annotation. In my contextInitialized 方法我做了一些设置工作并验证预期的资源是否可用。

如果我在那个 contextInitialized 方法中确定有问题,我该如何阻止 Web 应用程序继续执行 servlet?如果环境不合适(例如没有可用的数据库),这些 servlet 不应执行。

如何优雅地处理基于 servlet 的 Web 应用程序的故障环境?

不,ServletContextListener 界面似乎不是设计的目的是为了能够阻止网络应用程序的启动。

this Answer 所述,Servlet 规范表示 ServletContextListener 可能 在遇到异常时以某种方式禁用对 Web 应用程序的访问。 may 这个词的意思是可选的,不是必需的。该规范也没有准确定义停止访问网络应用程序的含义。

显然,各种 Web 容器中的实现行为差异很大。有些什么都不做,有些记录下来并继续,有些阻止 Web 应用程序的部署。

我对 Tomcat 8.0.33 的体验...将 throw new RuntimeException ( "bogus stop servlet " ); 放在 contextInitialized 方法中会阻止应用程序的部署。 IDE 报告中部署期间的控制台报告“FAIL - 在上下文路径部署应用程序/但上下文无法启动”。不幸的是,控制台和日志的 none 都没有捕捉到实际异常的报告。所以如果你从一个或多个侦听器中抛出多个异常,调试将不会很明显。

正如 Stack Overflow 中其他地方提到的,最可靠的解决方案可能是让您的 ServletContextListener 使用存储在 servlet 会话中的标志变量来标记成功或失败。然后让您的 servlet 代码检索并检查该标志。然后您的 servlet 代码将确定适当的操作过程。您的 Web 应用程序将被部署,但您自己的 servlet 可以选择不执行任何操作并发回一些 HTTP 错误代码。

类似问题:

  • Abort java webapp on startup
  • How can I make a ServletContextListener stop the Java EE application?
  • Prefered way to handle Java exceptions in ServletContextListener
  • Prevent Java EE application start on WebSphere on exception
  • ServletContextListener execution order
  • Stop Servlet context from initializing in init method

旁注:添加或编辑 ServletContextListener 时,您可能需要对项目执行 'clean-and-build' 操作。您的 IDE 的热插拔或边开发边部署功能可能无法接收新的或更改后的侦听器。跟踪您的代码或进行一些日志记录以进行验证。