我正在捕捉所有例外情况: java.lang.Throwable中 /page.xhtml java.lang.Error的 /page.xhtml
但是,如果我得到例如一个休眠的ex: org.hibernate.exception.ConstraintViolationException
我是否必须为每个可能发生的异常定义错误页面?我不能只说“抓住每一个例外”吗?
更新
重定向404工作。但是对于一个扔掉的人不会!
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.xhtml</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error.xhtml</location>
</error-page>
答案 0 :(得分:1)
有一种更好的方法来处理JSF中的异常 - 通过自定义异常处理程序,可以在faces-config.xml
中设置:
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<factory>
<exception-handler-factory>com.mycompany.CustomExceptionHandlerFactory</exception-handler-factory>
</factory>
</faces-config>
在这种情况下,您可以检查异常,它是根本原因并执行您想要的任何操作,因为您始终可以使用FacesContext
。以下是如何处理恼人的ViewExpiredException
:
厂:
public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
return new CustomExceptionHandler(parent.getExceptionHandler());
}
}
处理程序:
public class CustomExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
public CustomExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public ExceptionHandler getWrapped() {
return wrapped;
}
@Override
public void handle() throws FacesException {
Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
while (i.hasNext()) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
Throwable t = context.getException();
FacesContext fc = context.getContext();
boolean exceptionHandled = handleException(t, fc);
if(exceptionHandled) i.remove(); // remove from queue
}
getWrapped().handle(); // let wrapped ExceptionHandler do the rest
}
private boolean handleException(Throwable t, FacesContext fc) {
if (t instanceof ViewExpiredException) {
try {
fc.getExternalContext().redirect("/expired/url/");
return true;
} catch (IOException e) {
throw new FacesException(e);
}
} else return false;
}
}
答案 1 :(得分:0)
java.lang.Throwable
类是Java异常类层次结构中所有类的最不常见的祖先。所有异常和错误类都直接或间接地扩展Throwable
。
如果您有Throwable
的错误页面,那么任何没有更具体错误页面的异常都会在那里结束。
因此,您的问题的答案是“否”。如果你想(你认为合适的任何粒度),你可以单独处理Hibernate异常,但你不需要。
<强>更新强>
异常不会产生错误页面的原因有很多种。例如,它们可能在重定向处理期间发生,或者它们可能被过滤器捕获。或者他们可能会在提交响应标头之后被抛出;例如如果在格式化响应HTML期间发生异常。
(一个突出的线索是,当你抛出异常时,你是否正在任何错误页面。如果你得到一个'500'错误页面,那么某些东西正在发生。如果没有,那么你可能处于阻止任何错误页面生成的情况之一。)
无论如何,这是Servlet规范(3.0版)所说的。仔细阅读。
允许开发人员自定义返回给Web客户端的内容的外观 当servlet生成错误时,部署描述符定义错误列表 页面描述。语法允许返回资源的配置 当servlet或过滤器对响应调用sendError时的容器 特定的状态代码,或者servlet是否生成传播的异常或错误 到容器。
如果在响应上调用了sendError方法,则容器会查询列表 使用状态代码语法的Web应用程序的错误页面声明 尝试比赛。如果匹配,容器将返回指示的资源 通过位置输入。
servlet或过滤器在处理过程中可能会抛出以下异常 请求:
- 运行时异常或错误
- ServletExceptions或其子类
- IOExceptions或其子类
Web应用程序可能使用异常类型声明了错误页面 元件。在这种情况下,容器通过比较来匹配异常类型 使用异常类型的错误页面定义列表抛出异常 元件。匹配导致容器返回指示的资源 位置输入。类层次结构中最接近的匹配获胜。
如果没有包含异常类型的错误页面声明适合使用该类 - 层次结构匹配,抛出的异常是ServletException或子类 其中,容器提取包装的异常,如由其定义的 ServletException.getRootCause方法。对错误进行第二次传递 页面声明,再次尝试匹配错误页面声明, 但改为使用包装的异常。
在部署中使用exception-type元素的错误页面声明 描述符必须是唯一的,直到异常类型的类名。同样的, 使用status-code元素的错误页面声明必须是唯一的 部署描述符,直到状态码。
描述的错误页面机制在发生错误时不会介入 使用RequestDispatcher或filter.doFilter方法调用。这样,一个 使用RequestDispatcher的过滤器或servlet有机会处理错误 生成。
如果servlet生成错误页面机制未处理的错误,则为 如上所述,容器必须确保发送状态为500的响应。 默认的servlet和容器将使用sendError方法发送4xx和 5xx状态响应,以便可以调用错误机制。默认 servlet和容器将使用setStatus方法进行2xx和3xx响应 不会调用错误页面机制。
如果应用程序正在使用第2.3.3.3节中描述的异步操作, 第2-10页的“异步处理”,应用程序负责 处理应用程序创建的线程中的所有错容器可以照顾 来自AsyncContext.start发出的线程的错误。用于处理错误 在AsyncContext.dispatch期间发生,请参见第n节“任何错误或异常 在执行调度方法期间可能发生的事情必须被捕获 由容器处理如下:“第2-16页