Web xml 中的自定义异常映射不起作用

Custom exception mapping in web xml does not work

我的 JSF 2.2 webapp 在 web.xml 中有一个自定义异常映射,如下所示。

    <web-app 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-app_3_0.xsd"
    version="3.0">

    <display-name>Project</display-name>

    <!-- Welcome page -->
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <session-config>
       <!-- some codes-->
    </session-config>

    <error-page>
        <exception-type>se.telenor.ocfd.service.api.exception.CustomNotFoundException</exception-type>
        <location>/not_found.xhtml</location>
    </error-page>

    <error-page>
        <error-code>404</error-code>
        <location>/404.xhtml</location>
    </error-page>

    <error-page>
        <location>/500.xhtml</location>
    </error-page>

    <error-page>
        <exception-type>javax.faces.application.ViewExpiredException</exception-type>
        <location>/session_timeout.xhtml</location>
    </error-page>

</web-app>

我的例外是

@ApplicationException
public class CustomNotFoundException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public CustomNotFoundException(String message, Throwable cause) {
        super(message, cause);
    }

    public CustomNotFoundException(String message) {
        super(message);
    }
}

但是当异常发生时它执行 not redirect me to not_found.xhtml 页而不是 always redirect to 500.xhtml 页。

如果有任何遗漏,谁能帮助我。

如果异常包含在另一个异常中,则可能会发生这种情况,例如FacesException or ELException,取决于谁最先捕获实际异常并将其进一步委托给包装形式的调用者。然后,这只会匹配 <error-page>FacesExceptionELException.

的给定 <exception-type>

解决它的一种方法是创建一个 servlet filter,它在 doFilter() 方法中执行如下操作:

try {
    chain.doFilter(request, response);
}
catch (ServletException e) {
    Throwable cause = e.getRootCause();

    if (cause instanceof FacesException || cause instanceof ELException) {
        throw new ServletException(cause.getCause()); // Unwrap and rethrow it.
    }
    else {
        throw e;
    }
}

通过 /* 的 URL 模式将其映射到 FacesServlet 或应用范围。

如果您碰巧使用了 JSF 实用程序库 OmniFaces, a ready to use solution is available as FacesExceptionFilter.