JSP 错误页面产生 JSP 错误
我的 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 构建系统、升级的 jetty 和 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 控制器遇到未捕获的异常:
抛出新的 RuntimeException("no Bananas")
- 此异常由 springs 基 MultiActionController 捕获(因为没有自定义错误) handler 是为此页面定义的)异常被重新抛出:只是被 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 错误都会破坏它。但这不是页面应该出现的错误吗?
My spring-mvc web application has an error page with a collapsible stack trace element in it (obviously a development/debug option). This used to work just fine, and displayed the proper stack trace from the controller (or sometimes from the JSP engine).
Q: Is it possible to have a JSP be an error page, or should it be static HTML?
Q: What am I doing wrong?
The chain of events is (I think) driven by an error handler defined in my web.xml:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/view/errors/internalError.jsp</location>
</error-page>
Somewhere along the way (switched to a maven build system, upgraded jetty, and spring 2.5 -> 3.0), I noticed that this error page stopped working the way it had been. It renderes the same with one problem -- the exception stack-trace displayed is NOT from the exception thrown in the controller, but from the error page itself!
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)
What seems to be happening here, is the following chain of events:
- Spring controller hits an uncaught exception:
throw new RuntimeException("no bananas")
- This exception is caught by springs base MultiActionController (since no custom error handler is defined for this page) the exception is re-thrown: only to be caught again by spring's DispatcherServlet.
- The DispatcherServlet then looks at something (probably my web.xml) to discover the proper error page for the type of exception:
- Spring then resolves this URL to a view (and my error JSP) and tries to render it.
- Now here something goes wrong with the default parent jsp (* see below), throwing a JSP exception which gets caught, this time, by jetty's ServletHolder. This exception is now mapped (via web.xml) to the error JSP page.
- Here you might think that this would result in an infinite loop. However, the second time around things work out just fine and it renders the JSP error.
The JSP engine seems to die when rendering the default parent JSP -- it seems to run into trouble in: org.apache.taglibs.standard.tag.common.core.ImportSupport
. I've seen some web posts where people say it has to do with the import being from a WEB-INF directory.
// disallow inappropriate response codes per JSTL spec
if (irw.getStatus() < 200 || irw.getStatus() > 299) {
throw new JspTagException(irw.getStatus() + " " + stripSession(targetUrl));
}
Though it looks here like any HTTP 500 error would break it. But is that not what error the page should have?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
完全没问题。它甚至可以是一个 servlet 或其他东西。当然只要没有bug就可以。
您的错误页面有一个错误。显然,您在错误页面内使用
来包含/WEB-INF
中的片段。这是不允许的,因为它不是公共资源(老实说,我不记得它在古代 JSTL 版本中是否有效)。而是使用
。It's perfectly fine. It can even be a servlet or something. As long as it doesn't have bugs of course.
Your error page has a bug. You're apparently using
<c:import>
inside the error page to include a fragment from/WEB-INF
. This is disallowed because it's not a public resource (honestly I don't recall that it would ever have worked in ancient JSTL versions). Rather use<jsp:include>
.