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

查看:35
本文介绍了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.

推荐答案

这是因为 ViewExpiredException 被包裹在一个 ServletException 根据 JSF 规范.下面是 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:

调用保存的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:

如果 no error-page 声明包含 exception-type 适合使用class-hierarchy 匹配,并且抛出的异常是 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 替换为 javax.servlet.ServletException 作为 > 并重试.您将看到显示的预期错误页面.

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 页面,部署并运行它,然后在网络浏览器中打开它.
  2. 返回 Eclipse,右键单击 Tomcat 服务器并选择 Clean Tomcat Work Directory.这将重新启动 Tomcat 垃圾所有序列化会话(重要!仅重新启动 Tomcat 是不够的).
  3. 返回网络浏览器并按下命令按钮(无需事先重新加载页面!).
  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天全站免登陆