web.xml 中的 java.lang.Throwable 错误页面中显示 ViewExpiredException
我正在开发一个 JSF Web 应用程序,在该应用程序中,如果视图过期,我需要调出“会话过期”页面,但对于所有其他页面,则需要调出一般技术错误页面。当我触发异常时,应用程序仅进入技术错误页面。以下是错误页面定义:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/jsps/utility/sessionExpired.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/jsps/utility/technicalError.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/jsps/utility/technicalError.jsp</location>
</error-page>
我删除了 TechnicalError.jsp 错误页面元素并且工作正常,但是当我将它们放回去时,我无法访问 sessionExpired.jsp 页面。如何告诉 Web 容器评估这些标签的顺序,以便出现正确的页面?谢谢。
I'm working on a JSF web application in which I need to bring up a "Session Expired" page if the view expires, but a general technical error page for all others. The application only goes to the technical error page when I trigger the exception. Here's the error-page definitions:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/jsps/utility/sessionExpired.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/jsps/utility/technicalError.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/jsps/utility/technicalError.jsp</location>
</error-page>
I removed the technicalError.jsp error page elements and it worked fine, but when I put them back I can't get to the sessionExpired.jsp page. How do I tell the web container the order to evaluate these tags so that the right page comes up? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是因为
ViewExpiredException
被包装在ServletException< /code>
根据 JSF 规范。以下是 JSF 1.2 规范第 10.2.6.2 章的摘录:
Servlet API 规范中指定了错误页面的分配方式。以下是 Servlet API 规范 2.5 第 9.9.2 章的摘录:
在类层次结构中,
ServletException
已经与Throwable
匹配,因此第二遍不会提取其根本原因。要证明此指定行为,请将
javax.faces.application.ViewExpiredException
替换为javax.servlet.ServletException
作为
并重试。您将看到显示预期的错误页面。要解决此问题,只需删除
java.lang.Throwable
或java.lang.Exception
上的错误页面即可。如果没有一个异常特定错误页面匹配,那么无论如何它都会回退到错误代码500
的页面。因此,您所需要的就是:更新:根据OP的(已删除)注释:要可靠地测试这一点,您不能在a中
抛出新的ViewExpiredException()
bean 构造函数或方法等等。它反过来会被一些 EL 异常包裹起来。您最终可以在Filter
中添加一条打印rootCause
的调试行来亲自查看。如果您使用 Eclipse/Tomcat,测试
ViewExpiredException
的快速方法如下:This is because the
ViewExpiredException
is been wrapped in aServletException
as per the JSF specification. Here's an extract of chapter 10.2.6.2 of the JSF 1.2 specification:How the error pages are allocated is specified in Servlet API specification. Here's an extract of chapter 9.9.2 of Servlet API specification 2.5:
In class hierarchy,
ServletException
already matchesThrowable
, so its root cause won't be extracted for the second pass.To prove this specified behaviour, replace
javax.faces.application.ViewExpiredException
byjavax.servlet.ServletException
as<exception-type>
and retry. You'll see the expected error page being displayed.To solve this, simply remove the error page on
java.lang.Throwable
orjava.lang.Exception
. If no one exception specific error page matches, then it will fall back to the one for error code of500
anyway. So, all you need is this:Update: as per the (deleted) comment of the OP: to reliably test this you cannot do a
throw new ViewExpiredException()
in a bean constructor or method or so. It would in turn get wrapped in some EL exception. You can eventually add a debug line printingrootCause
in theFilter
to see it yourself.If you're using Eclipse/Tomcat, a quick way to test
ViewExpiredException
is the following:正如 BylusC 所提到的,部署描述符不得包含任何将捕获 ViewExpiredException(包装在 ServletException 内)的错误页面处理程序,而不是包含正确的错误页面 - ViewExpiredException 的错误页面。
不要忘记验证服务器的部署描述符(例如 TomEE/conf/web.xml)不包含 java.lang.Throwable 或 java.lang.Exception 错误页面定义。因为这两个web.xml基本上是合并了。
是 - 应用程序的 web.xml 优先于服务器的 web.xml,但如果应用程序的 web.xml 包含
以及服务器的 web.xml 的
那么应用程序上下文将包含这两者的合并:
和 ViewExpiredExcpetion 错误处理将无法正常工作。
As mentioned by BylusC, deployment descriptor must not contain any error-page handler that will catch ViewExpiredException (wrapped inside ServletException) instead of the correct one - error-page for ViewExpiredException.
Do not forget to verify that server's deployment descriptor (e.g. TomEE/conf/web.xml) does not contain java.lang.Throwable or java.lang.Exception error-page definitions. Because these two web.xml are basically merged.
Yes - application's web.xml has precedence over server's web.xml, but if application's web.xml contains
and server's web.xml for
then application context will contain merge of those two:
and ViewExpiredExcpetion error handling will not work correctly.