web.xml中的java.lang.Throwable错误页面中显示的ViewExpiredException [英] ViewExpiredException shown in java.lang.Throwable error-page in web.xml

查看:426
本文介绍了web.xml中的java.lang.Throwable错误页面中显示的ViewExpiredException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个JSF 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>

我删除了technicalError.jsp错误页面元素,并且工作正常,但是当我放回它们时,我无法进入sessionExpired.jsp页面.如何告诉Web容器评估这些标签的顺序,以便显示正确的页面?谢谢.

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.

推荐答案

这是因为 ServletException .这是 JSF 1.2规范的第10.2.6.2章的摘录:

This is because the ViewExpiredException is been wrapped in a ServletException as per the JSF specification. Here's an extract of chapter 10.2.6.2 of the JSF 1.2 specification:

10.2.6.2 FacesServlet

调用已保存的Lifecycle实例的execute()方法,并传递 此请求的FacesContext实例作为参数.如果execute()方法 抛出FacesException将其重新抛出为ServletException FacesException是根本原因.

10.2.6.2 FacesServlet

Call the execute() method of the saved Lifecycle instance, passing the FacesContext instance for this request as a parameter. If the execute() method throws a FacesException, re-throw it as a ServletException with the FacesException as the root cause.

如何分配错误页面在Servlet API规范中指定.这是 Servlet API规范2.5 的第9.9.2章的摘录:

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:

SRV.9.9.2错误页面

如果包含exception-type error-page声明适合使用 类层次结构匹配,并且抛出的异常是ServletException或 子类,容器提取包装的异常,如 ServletException.getRootCause方法.对错误进行了第二遍 页面声明,再次尝试与错误页面匹配 声明,但改用包装的异常.

SRV.9.9.2 Error Pages

If no error-page declaration containing an exception-type fits using the class-hierarchy match, and the exception thrown is a ServletException or subclass thereof, the container extracts the wrapped exception, as defined by the ServletException.getRootCause method. A second pass is made over the error page declarations, again attempting the match against the error page declarations, but using the wrapped exception instead.

在类层次结构中,ServletException已经与Throwable匹配,因此第二遍将不会提取其根本原因.

In class hierarchy, ServletException already matches Throwable, so its root cause won't be extracted for the second pass.

要证明此指定的行为,请将javax.faces.application.ViewExpiredException替换为<exception-type>,然后重试.您会看到预期的错误页面正在显示.

To prove this specified behaviour, replace javax.faces.application.ViewExpiredException by javax.servlet.ServletException as <exception-type> and retry. You'll see the expected error page being displayed.

要解决此问题,只需删除错误页面上的java.lang.Throwablejava.lang.Exception.如果没有一个特定于异常的错误页面匹配,则无论如何它都会退回到错误代码为500的页面.所以,您只需要这样:

To solve this, simply remove the error page on java.lang.Throwable or java.lang.Exception. If no one exception specific error page matches, then it will fall back to the one for error code of 500 anyway. So, all you need is this:

<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>


更新:根据OP的(已删除)注释:要可靠地进行测试,您不能在Bean构造函数或方法中执行throw new ViewExpiredException().反过来,它将被包裹在某些EL异常中.您最终可以在Filter中添加打印rootCause的调试行以自己查看.


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 printing rootCause in the Filter to see it yourself.

如果您使用的是Eclipse/Tomcat,则可以使用以下快速测试ViewExpiredException的方法:

If you're using Eclipse/Tomcat, a quick way to test ViewExpiredException is the following:

  1. 使用一个简单的命令按钮创建一个JSF页面,部署并运行它,然后在webbrowser中打开它.
  2. 返回Eclipse,右键单击Tomcat服务器,然后选择"清洁Tomcat工作目录" .这将重新启动Tomcat ,并丢弃所有序列化的会话(重要!仅重新启动Tomcat是不够的).
  3. 返回Web浏览器并按命令按钮(事先没有重新加载页面!).
  1. Create a JSF page with a simple command button, deploy and run it and open it in webbrowser.
  2. Go back to Eclipse, rightclick Tomcat server and choose Clean Tomcat Work Directory. This will restart Tomcat and trash all serialized sessions (important! just restarting Tomcat is not enough).
  3. Go back to webbrowser and press the command button (without reloading page beforehand!).

这篇关于web.xml中的java.lang.Throwable错误页面中显示的ViewExpiredException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆