Reputation: 17873
I have in my JSF 2.2 webapp a custom exception mapping in web.xml as below.
<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>
My Exception is
@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);
}
}
But it does not redirect me to not_found.xhtml
page but instead always redirect to 500.xhtml
page when the exception happens.
Can some one help me if any thing missing.
Upvotes: 1
Views: 1329
Reputation: 1108567
That can happen if the exception is wrapped in another exception, e.g. FacesException
or ELException
, depending on who was the first to catch the actual exception and delegating it further to the caller in wrapped form. This would then only match an <error-page>
with exactly the given <exception-type>
of FacesException
or ELException
.
One way to solve it is creating a servlet filter which does something like below in doFilter()
method:
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;
}
}
Map it to the FacesServlet
or perhaps application wide via an URL pattern of /*
.
If you happen to use JSF utility library OmniFaces, a ready to use solution is available as FacesExceptionFilter
.
Upvotes: 5