有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java捕获hibernate异常与errorpage处理程序?

我正在捕获以下范围内的所有异常: JAVA可丢弃的 /页面。xhtml JAVA语言错误 /页面。xhtml

但如果我得到一个冬眠前: 组织。冬眠例外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>

共 (2) 个答案

  1. # 1 楼答案

    java.lang.Throwable类是Java异常类层次结构中所有类中最不常见的祖先。所有异常和错误类都直接或间接地扩展Throwable

    如果Throwable有一个错误页面,任何没有更具体错误页面的异常都会在那里结束

    因此,你的问题的答案是“不”。如果愿意,可以单独处理Hibernate异常(以您认为合适的任何粒度),但不必这样做


    更新

    异常没有生成错误页面的原因有很多。例如,它们可能发生在重定向处理过程中,或者可能被筛选器捕获。或者,在提交了响应头之后,可能会抛出它们;e、 g.如果在格式化响应HTML期间发生异常

    (一个显著的线索是,当抛出异常时,您是否得到了任何错误页面。如果您得到的是'500'错误页面,则发生了一些。如果没有,则您可能处于阻止任何错误页面生成的情况之一。)

    无论如何,下面是Servlet规范(3.0版)的说明。仔细阅读


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

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

    • runtime exceptions or errors
    • ServletExceptions or subclasses thereof
    • IOExceptions or subclasses thereof

    The Web application may have declared error pages using the exception-type element. 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. 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. 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. 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. In this way, a filter or servlet using the RequestDispatcher has the opportunity to handle errors generated.

    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. The default servlet and container will use the setStatus method for 2xx and 3xx responses and will not invoke the error page mechanism.

    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. The container MAY take care of the errors from the thread issued via 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

  2. # 2 楼答案

    有一种更好的方法可以在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;
      }
    }