We have seen all success scenarios till now. However what if there is exception? how to handle those in RESTful webservices? Handling of exception mainly includes how to return meaningful message to end client.
There are couple of ways to handle exception in RESTful webservices. First we will look into using "ExceptionMapper ". javax.ws.rs.ext.ExceptionMapper is interface which have one method to be implemented 'toResponse(E exception)'.
We can implement this interface and create mapper for each type of exception which application can throw. We can have one generic mapper as well to cover all types of exception like mapper for "Throwable".
In last tutorial, we have seen deletion of product method which takes productId and based on that, it deletes the product. But what if there is no product for given productId and application throws 'EntityNotFoundException'?
Let's see how response looks like with this exception,
delete method is below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @DELETE @Path("{productId}") @Produces(MediaType.TEXT_PLAIN) public final Response deleteProduct(@PathParam("productId") final int productId) throws EntityNotFoundException { final ProductDao productDao = new ProductDao(); final boolean isDeleted = productDao.deleteProduct(productId); if (isDeleted) { return Response.status(Status.OK) .header("RESOURCE_DELETED", "TRUE") .entity("Resource deleted successfully!").build(); } else { throw new EntityNotFoundException("Product with id " + productId + " not found."); } } |
EntityNotFoundException is custom exception type as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package in.blogspot.ashish4java.invoicedetails.exception; public class EntityNotFoundException extends Exception { /** * */ private static final long serialVersionUID = -3227525992494807317L; public EntityNotFoundException(final String errorMessage) { super(errorMessage); } } |
With this, if there is deletion request for product which doesn't exists then response looks like below,
What is problem with this response:
- It doesn't return user friendly error message. It returns standard tomcat error message which doesn't provide additional information on why exception was thrown.
- Status code returned is 500 which is 'Internal Server Error' however as this is business error we want to set to something like "404 Not Found" for resource not found.
So, let's create ExceptionMapper for this as below,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package in.blogspot.ashish4java.invoicedetails.exception; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; @Provider public class EntityNotFoundExceptionMapper implements ExceptionMapper<EntityNotFoundException> { @Override public Response toResponse(EntityNotFoundException e) { return Response.status(Status.NOT_FOUND).header("RESOURCE_FOUND", "FALSE") .entity(e.getMessage()) .build(); } } |
Note down @Provider annotation which registers this exception mapper in JAX-RS runtime. This declares that the class is of interest to the JAX-RS runtime. toResponse builds the response object by setting status code, response header and error message as response content.
With this, when an application throws an EntityNotFoundException, the toresponse method of the
EntityNotFoundExceptionMapper
instance will be invoked.
If there is request to delete Product which does not exists then response will be like below,
Status code is 404 Not found and response content clearly states reason for what went wrong.
This is all about exception mappers.
The other way to handle exception is to throw 'WebApplicationException' or one of subclasses of it. However sometimes this approach is not preferable. This approach either needs to modify existing custom exception type which needs to extend 'WebApplicationException' or have to use existing subclass of WebApplicationException exception.
In both scenarios, this approach doesn't provide flexibility as first approach of using Exceptionmapper.
In next tutorial, we will see how to use subresources. Thanks for reading this and STAY TUNED!
No comments:
Post a Comment