我的 spring-mvc Web 应用程序有一个错误页面,其中包含一个可折叠的堆栈跟踪元素(显然是一个开发/调试选项)。这过去工作得很好,并显示了来自控制器(或有时来自 JSP 引擎)的正确堆栈跟踪。
问:JSP 是否可以是错误页面,还是应该是静态 HTML?
问:我做错了什么?
事件链(我认为)由我的 web.xml 中定义的错误处理程序驱动:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/view/errors/internalError.jsp</location>
</error-page>
一路走来(切换到 maven 构建系统、升级码头和 spring 2.5 -> 3.0),我注意到这个错误页面停止工作。它呈现相同的一个问题——显示的异常堆栈跟踪不是来自控制器中抛出的异常,而是来自错误页面本身!
javax.servlet.ServletException: javax.servlet.jsp.JspTagException:
500 /WEB-INF/jsp/admin/errors/internalError.jsp
at org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:862)
at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:791)
at org.apache.jsp.WEB_002dINF.jsp.admin.defaultParent_jsp._jspService(defaultParent_jsp.java:225)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
这里似乎发生了以下一系列事件:
- Spring 控制器遇到未捕获的异常:
throw new RuntimeException("no bananas")
- 此异常由 springs 基础 MultiActionController 捕获(因为没有为此页面定义自定义错误处理程序)异常被重新抛出:仅由 spring 的 DispatcherServlet 再次捕获。
- 然后 DispatcherServlet 会查看某些内容(可能是我的 web.xml)以发现异常类型的正确错误页面:
- 然后 Spring 将此 URL 解析为视图(以及我的错误 JSP)并尝试呈现它。
- 现在这里默认的父 jsp 出了点问题(* 见下文),抛出了一个 JSP 异常,这一次被 jetty 的 ServletHolder 捕获。此异常现在(通过 web.xml)映射到错误 JSP 页面。
- 在这里您可能会认为这会导致无限循环。但是,第二次解决问题就很好了,它呈现了 JSP 错误。
在呈现默认父 JSP 时,JSP 引擎似乎死机了——它似乎在:org.apache.taglibs.standard.tag.common.core.ImportSupport
. 我看过一些网络帖子,人们说这与从 WEB-INF 目录中导入有关。
// disallow inappropriate response codes per JSTL spec
if (irw.getStatus() < 200 || irw.getStatus() > 299) {
throw new JspTagException(irw.getStatus() + " " + stripSession(targetUrl));
}
虽然在这里看起来任何 HTTP 500 错误都会破坏它。但这不是页面应该有的错误吗?