简体   繁体   English

使用错误页面处理程序捕获休眠异常?

[英]Catch hibernate exceptions with errorpage handler?

I'm catching all exceptions within: java.lang.Throwable /page.xhtml java.lang.Error /page.xhtml 我正在捕获以下所有异常:java.lang.Throwable /page.xhtml java.lang.Error /page.xhtml

But what If I get eg a hibernate ex: org.hibernate.exception.ConstraintViolationException 但是如果我得到一个休眠的例子,例如:org.hibernate.exception.ConstraintViolationException,该怎么办?

Do I have to define error-pages for EVERY maybe occuring exception? 我是否必须为每个可能发生的异常定义错误页面? Can't I just say "catch every exception"? 我不能只说“抓住每一个例外”吗?

Update 更新资料

Redirect on a 404 works. 重定向到404作品。 But on a throwable does not! 但是就不会抛出!

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

There is a better way to handle exceptions in JSF - via custom exception handler which can be set in your faces-config.xml : 在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>

In that case you can examine exception, it's root cause and perform any actions you want as you will always have handy FacesContext . 在这种情况下,您可以检查异常的根本原因,并执行所需的任何操作,因为您将始终拥有方便的FacesContext Below is an example how to handle annoying ViewExpiredException : 下面是一个如何处理烦人的ViewExpiredException

Factory: 厂:

public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {
  private ExceptionHandlerFactory parent;

  public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
    this.parent = parent;
  }

  @Override
  public ExceptionHandler getExceptionHandler() {
    return new CustomExceptionHandler(parent.getExceptionHandler());
  }
}

Handler: 处理程序:

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

The java.lang.Throwable class is the least common ancestor of all classes in the Java exception class hierarchy. java.lang.Throwable类是Java异常类层次结构中所有类中最不常见的祖先。 All exception and error classes extend Throwable , directly or indirectly. 所有异常和错误类都直接或间接扩展Throwable

If you have an error page for Throwable , any exception that doesn't have a more specific error page will end up there. 如果您有一个Throwable错误页面,那么没有更具体的错误页面的任何异常都将在那里结束。

Therefore, the answer to your question is "No". 因此,您的问题的答案是“否”。 You can handle Hibernate exceptions separately if you want to (at any granularity you think is appropriate), but you don't have to. 如果愿意(可以认为合适的任何粒度),都可以单独处理Hibernate异常,但是不必这样做。


UPDATE 更新

There are a number of possible reasons why the exceptions are not producing error pages. 有许多可能的原因导致异常不产生错误页面。 For example, they might be occurring during redirect processing or they might be caught by a filter. 例如,它们可能在重定向处理期间发生,或者可能被过滤器捕获。 Or they might be thrown after the response header has been committed; 否则,它们可能会响应头提交抛出; eg if the exception occurs during the formatting of the response HTML. 例如,如果在响应HTML的格式化期间发生异常。

(One salient clue will be whether you are getting any error page at all when an exception is thrown. If you are getting a '500' error page then something is happening. If not then you are probably in one of those situations which prevent any error page generation.) (一个明显的线索是,抛出异常时,您是否会得到任何错误页面 。如果得到的是“ 500”错误页面,则说明正在发生某种情况。如果没有,则可能是在其中一种情况下,您无法错误页面生成。)

Anyway, here is what the Servlet spec (version 3.0) says. 无论如何,这就是Servlet规范(版本3.0)所说的。 Read it carefully. 请仔细阅读。


10.9.2 Error Pages 10.9.2错误页面

To allow developers to customize the appearance of content returned to a Web client when a servlet generates an error, the deployment descriptor defines a list of error page descriptions. 为了允许开发人员自定义servlet生成错误时返回到Web客户端的内容的外观,部署描述符定义了错误页面描述的列表。 The syntax allows the configuration of resources to be returned by the container either when a servlet or filter calls sendError on the response for specific status codes, or if the servlet generates an exception or error that propagates to the container. 该语法允许当servlet或过滤器在响应中针对特定状态代码调用sendError时,或者如果servlet生成传播到容器的异常或错误时,容器将返回资源配置。

If the sendError method is called on the response, the container consults the list of error page declarations for the Web application that use the status-code syntax and attempts a match. 如果在响应上调用sendError方法,则容器将查询使用状态码语法的Web应用程序的错误页面声明列表,并尝试进行匹配。 If there is a match, the container returns the resource as indicated by the location entry. 如果存在匹配项,则容器将返回该资源,如位置条目所示。

A servlet or filter may throw the following exceptions during processing of a request: Servlet或过滤器在处理请求期间可能会引发以下异常:

  • runtime exceptions or errors 运行时异常或错误
  • ServletExceptions or subclasses thereof ServletExceptions或其子类
  • IOExceptions or subclasses thereof IOExceptions或其子类

The Web application may have declared error pages using the exception-type element. Web应用程序可能已使用exception-type元素声明了错误页面。 In this case the container matches the exception type by comparing the exception thrown with the list of error-page definitions that use the exception-type element. 在这种情况下,容器通过将抛出的异常与使用exception-type元素的错误页面定义列表进行比较来匹配异常类型。 A match results in the container returning the resource indicated in the location entry. 匹配导致容器返回位置条目中指示的资源。 The closest match in the class hierarchy wins. 类层次结构中最接近的匹配获胜。

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. 如果没有通过类层次结构匹配使用包含异常类型的错误页面声明,并且抛出的异常是ServletException或其子类,则容器将提取包装的异常,该异常由ServletException.getRootCause方法定义。 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. 对错误页面声明进行第二遍处理,再次尝试与错误页面声明进行匹配,但改用包装的异常。

Error-page declarations using the exception-type element in the deployment descriptor must be unique up to the class name of the exception-type. 在部署描述符中使用exception-type元素的错误页面声明必须唯一,直到exception-type的类名为止。 Similarly, error-page declarations using the status-code element must be unique in the deployment descriptor up to the status code. 同样,使用状态码元素的错误页面声明在部署描述符中必须唯一,直到状态码为止。

The error page mechanism described does not intervene when errors occur when invoked using the RequestDispatcher or filter.doFilter method. 当使用RequestDispatcher或filter.doFilter方法调用时发生错误时,描述的错误页面机制不会干预。 In this way, a filter or servlet using the RequestDispatcher has the opportunity to handle errors generated. 这样,使用RequestDispatcher的筛选器或Servlet就有机会处理所生成的错误。

If a servlet generates an error that is not handled by the error page mechanism as described above, the container must ensure to send a response with status 500. The default servlet and container will use the sendError method to send 4xx and 5xx status responses, so that the error mechanism may be invoked. 如果Servlet产生了如上所述的错误页面机制未处理的错误,则容器必须确保发送状态为500的响应。默认Servlet和容器将使用sendError方法发送4xx和5xx状态响应,因此错误机制可以被调用。 The default servlet and container will use the setStatus method for 2xx and 3xx responses and will not invoke the error page mechanism. 默认的servlet和容器将对2xx和3xx响应使用setStatus方法,并且不会调用错误页面机制。

If the application is using asynchronous operations as described in Section 2.3.3.3, “Asynchronous processing” on page 2-10, it is the application's responsibility to handle all errors in application created threads. 如果应用程序使用第2-10页的第2.3.3.3节“异步处理”中所述的异步操作,则应用程序有责任处理应用程序创建的线程中的所有错误。 The container MAY take care of the errors from the thread issued via AsyncContext.start. 容器可以处理通过AsyncContext.start发出的线程中的错误。 For handling errors that occur during AsyncContext.dispatch see Section n, “Any errors or exceptions that may occur during the execution of the dispatch methods MUST be caught and handled by the container as follows:” on page 2-16 有关处理在AsyncContext.dispatch期间发生的错误,请参阅第2-16页,第n节“必须由容器捕获并处理在执行分派方法期间可能发生的任何错误或异常:”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM