JSF Exception Handler for exception types

Goal

Mapping different exception types to different error pages, in a JSF application

Description

This recipe will show us how to use JBoss Solder to implement an exception handler that sends the user to a specific page, when an exception is thrown on any JSF backing bean call

How to

First, and assuming that you are working on a Maven project, you have to define the JBoss Solder dependencies, as the following:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
          http://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <properties>
    <!-- Solder -->
    <solder.version>3.1.0.Final</solder.version>
  </properties>

  <dependencies>
    <!-- Exception handling -->
    <dependency>
      <groupId>org.jboss.solder</groupId>
      <artifactId>solder-api</artifactId>
      <version>${solder.version}</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.jboss.solder</groupId>
      <artifactId>solder-impl</artifactId>
      <version>${solder.version}</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
...
</project>

Next, we implement our exception handler, as follows, where we specify the class as being an exception handler through the specification of the annotation HandlesExceptions from Solder and, inside of it, we add new handler methods (marked as such through the definition of the annotation @Handles associated to the method argument CaughtException parameterized with the exception type we want to deal with)) for each exception type we want to deal with (in the example, only the exception ViewExpiredException has been taken care of.

import javax.faces.application.ViewExpiredException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.solder.exception.control.CaughtException;
import org.jboss.solder.exception.control.Handles;
import org.jboss.solder.exception.control.HandlesExceptions;
import org.jboss.solder.servlet.WebRequest;

@HandlesExceptions
public class ExceptionHandlers {

  public void handleViewExpiredException(
    @Handles(precedence = org.jboss.solder.exception.control.Precedence.HIGH) 
    @WebRequest CaughtException<ViewExpiredException> caught,
    final HttpServletRequest request, final HttpServletResponse response) {
    caught.handled();
    try {
      response.sendRedirect(response.encodeRedirectURL(
        request.getContextPath() + "/errors/timeout.xhtml"));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Notice additionally, in the previous method implementation, the call to caught.handled() which tells Solder that the exception type has already been taken care of and thus no other exception handler methods should treat this exception again.

Finally, and although not necessary, we may add the definition for the handling of the generic Java exception Exception in our web.xml (or corresponding web-fragment.xml) file and where we can also add a note for other developers to be aware of that the class ExceptionHandlers exist and what it does:

<!-- See class ExceptionHandlers for more exception handler cases -->
<error-page>
  <exception-type>java.lang.Exception</exception-type>
  <location>/errors/error.xhtml</location>
</error-page>

To test this implementation, we can now create a backing bean like the following:

@Named("catastrophyBean")
@RequestScoped
public class CatastrophyBean {

  public void generateViewExpiredException() {
    throw new ViewExpiredException();
  }
}

and the corresponding page to interact with the bean:

...
<h:form>
  <p:commandButton
    action="#{catastrophyBean.generateViewExpiredException()}"
    value="Generate View Expired Exception" ajax="false" />
</h:form>
...

Explanations

In JSF, we can map error pages to HTTP error codes with no problems. However, when we do that to exceptions, those are wrapped around other JSF exceptions that force us to implement some sort of exception handler (see, for instance, a sample implementation in coderanch). With JBoss Solder at use, we get a simple solution to map any type of exception to specific pages, as wanted

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s