Luk*_*uke 17 jsf web.xml servlets custom-error-pages viewexpiredexception
我正在开发一个JSF Web应用程序,如果视图过期,我需要在其中显示"Session Expired"页面,但是所有其他页面都需要一个常规技术错误页面.当我触发异常时,应用程序仅进入技术错误页面.这是错误页面定义:
<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>
Run Code Online (Sandbox Code Playgroud)
我删除了technicalError.jsp错误页面元素,它工作正常,但当我把它们放回去时,我无法访问sessionExpired.jsp页面.如何告诉Web容器评估这些标记的顺序,以便出现正确的页面?谢谢.
Bal*_*usC 16
这是因为它按照JSF规范ViewExpiredException包装ServletException.这是JSF 1.2规范第10.2.6.2节的摘录:
10.2.6.2 FacesServlet
调用已
execute()保存Lifecycle实例的方法,FacesContext将此请求的实例作为参数传递 .如果execute()方法引发FacesException,重新把它作为一个ServletException与FacesException为根本原因.
如何分配错误页面在Servlet API规范中指定.这是Servlet API规范2.5的第9.9.2节的摘录:
SRV.9.9.2错误页面
如果没有 使用类层次结构匹配的
error-page包含exception-type拟合的 声明,并且抛出的异常是其子类或子类,则容器将提取由方法定义的包装异常.对错误页面声明进行第二次传递,再次尝试匹配错误页面声明,但改为使用包装的异常.ServletExceptionServletException.getRootCause
在类层次结构中,ServletException已经匹配Throwable,因此第二遍不会提取其根本原因.
要证明此指定的行为,请替换javax.faces.application.ViewExpiredException为javax.servlet.ServletExceptionas <exception-type>并重试.您将看到正在显示的预期错误页面.
要解决此问题,只需删除错误页面java.lang.Throwable或java.lang.Exception.如果没有一个异常特定错误页面匹配,那么500无论如何它将回退到错误代码.所以,你需要的只是:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/jsps/utility/sessionExpired.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/jsps/utility/technicalError.jsp</location>
</error-page>
Run Code Online (Sandbox Code Playgroud)
更新:根据OP的(删除的)注释:为了可靠地测试它,你不能throw new ViewExpiredException()在bean构造函数或方法中执行.它反过来会包含在一些EL异常中.您最终可以rootCause在其中添加调试行打印Filter以自行查看.
如果您正在使用Eclipse/Tomcat,ViewExpiredException则可以通过以下方式快速测试:
| 归档时间: |
|
| 查看次数: |
15935 次 |
| 最近记录: |