我正在开发一个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容器评估这些标记的顺序,以便显示正确的页面?谢谢。
发布于 2010-07-09 05:14:32
这是因为按照JSF规范,ViewExpiredException
被包装在ServletException
中。以下是JSF 1.2 specification第10.2.6.2章的摘录
10.2.6.2 FacesServlet
调用保存的Lifecycle
实例的execute()
方法,将此请求的FacesContext
实例作为参数传递。如果execute()
方法抛出FacesException
,则以 ServletException
作为根本原因重新抛出它。
Servlet API规范中指定了如何分配错误页。以下是Servlet API specification 2.5第9.9.2章的摘录
SRV.9.9.2错误页
如果没有包含exception-type
的 error-page
声明符合类层次结构匹配,并且抛出的异常是ServletException
或其子类,则容器提取包装的异常,如ServletException.getRootCause
方法所定义的那样。对错误页声明进行第二遍,再次尝试与错误页声明进行匹配,但使用包装的异常。
在类层次结构中,ServletException
已经与Throwable
匹配,因此不会在第二次遍历时提取其根本原因。
要证明此指定行为,请将javax.faces.application.ViewExpiredException
替换为javax.servlet.ServletException
作为<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>
bean更新:根据OP的(已删除)注释:为了可靠地测试这一点,您不能在构造函数或方法中执行throw new ViewExpiredException()
。反过来,它会被某个EL异常所包裹。最后,您可以在Filter
中添加一个打印rootCause
的调试行,以亲自查看它。
如果您使用的是Eclipse/Tomcat,测试ViewExpiredException
的快速方法如下所示:
Tomcat使用一个简单的命令按钮创建一个页面,部署并运行它,然后在webbrowser.
)
发布于 2020-08-12 00:24:27
正如BylusC所提到的,部署描述符不能包含任何将捕获ViewExpiredException (包装在ServletException中)的错误页面处理程序,而不能包含正确的ViewExpiredException错误页面。
不要忘记验证服务器的部署描述符(例如TomEE/conf/web.xml)不包含java.lang.Throwable或java.lang.Exception错误页定义。因为这两个web.xml基本上是合并的。
是-应用程序的web.xml优先于服务器的web.xml,但如果应用程序的web.xml包含
500 (/error.xhtml)的
和服务器的web.xml
则应用程序上下文将包含这两者的合并:
并且ViewExpiredExcpetion错误处理将不能正常工作。
https://stackoverflow.com/questions/3206922
复制相似问题