Define exception mappers for resource exceptions and errors
Overview
The default behavior is to use the exception handling functionality of the application container such as JSP error pages. However, we can customize the error handling and send specific responses back when an exception or error occurs.
JAX-RS resource methods, like any Java method, can throw checked and unchecked exceptions. By default, an unchecked runtime exception or error occurs in the container again. A checked exception is wrapped in a ServletException for resources running in the web container. Therefore, a developer can use error handling facilities such as JSP error pages to handle exceptions thrown from a JAX-RS application.
JAX-RS introduced the exception...
javax.ws.rs.WebApplicationException
A developer can specify a specific error class name or javax.ws.rs.core.Response object when creating a WebApplicationException. When the WebApplicationException is thrown, the information included in the exception by way of a status class name or Response object is used to serialize a response.
If we cannot throw the exception, WebApplicationException, in the code and we cannot use the error handling facilities in the web container, but to use a custom error response, then we can create a customized JAX-RS javax.ws.rs.ext.ExceptionMapper class to map exceptions to HTTP error responses.
Write a custom ExceptionMapper class
- Create a class that implements the javax.ws.rs.ext.ExceptionMapper class, and annotate the class with the javax.ws.rs.ext.Provider annotation.
This step assumes that the JAX-RS resource can throw the exception, MyCustomException, in its methods. The following example illustrates a simple ExceptionMapper class:
import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; @Provider public class CustomExceptionMapper implements ExceptionMapper<MyCustomException> { public Response toResponse(MyCustomException exception) { return null; } }
- In the toResponse(MyCustomException) method, return a Response object containing the customized error response.
The following example illustrates a customized ExceptionMapper.toResponse(MyCustomException) method:
@Provider public class CustomExceptionMapper implements ExceptionMapper<MyCustomException> { public Response toResponse(MyCustomException exception) { return Response.status(500).entity("App cannot process the request at this time.").type("text/plain").build(); } }We can have additional code where you log an error, inspect the exception thrown, or use more complex logic.
- Package the compiled custom ExceptionMapper class with the web application project.
If we rely on the annotation scanning capabilities to find all of the JAX-RS classes in the web application, no additional steps are required. However, if you return all of the relevant JAX-RS resource classes and providers in a JAX-RS application subclass method, then you must also add the custom ExceptionMapper class to the returned set. The following example illustrates a preexisting javax.ws.rs.core.Application subclass:
import java.util.HashSet; import java.util.Set; import javax.ws.rs.core.Application; public class MyApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<Class<?>>(); classes.add(CustomExceptionMapper.class); /* add the additional JAX-RS classes here */ return classes; } }When exceptions occur in the JAX-RS resource methods, we can customize the HTTP error response so that a user cannot see a stack trace or potentially confidential data. Use an ExceptionMapper or the exception handling functionality in the web container to give more helpful responses if the application is not behaving correctly.
Results
You have written a custom ExceptionMapper to handle exceptions in the JAX-RS web application.
Related tasks
Configure JAX-RS applications using JAX-RS 1.1 methods