For example, assuming you have a basic REST endpoint such as:
@RequestMapping(value = "/samples", method = {RequestMethod.GET}) @ResponseBody public SampleList findAllSamples() throws SampleException { return new SampleList(service.findAllSamples()); }
It is good practice in general to not let implementation exceptions leave the service tier, so you might use aspects to catch these and rethrow them as service exceptions. The code below catches a ReferenceNotFoundException from the data access tier and throws a service exception with the reference number and setting the desired http status code. Another good practice is to avoid sending free text error messages to a service client, and instead to send structured messages that can be dealt with or rendered as the client sees fit.
@Aspect @Component("exceptionHandler") public class ExceptionHandler { /** * Exception handler for ReferenceNotFoundExceptions * * @param nfe the exception being handled */ @AfterThrowing(pointcut = "execution (* com.sample.service.*.*(..))",
throwing = "nfe") public void handleNotFoundException(ReferenceNotFoundException nfe) { throw new SampleException( new ReferenceNotFoundError(nfe.getReference()),
HttpStatus.NOT_FOUND); }Now to map the service exception (SampleException) to a meaningful HTTP response using the Spring 3 @ExceptionHandler annotation:
@ExceptionHandler(SampleException.class) @ResponseBody public SampleErrorList exceptionHandler(SampleException se, HttpServletRequest req, HttpServletResponse res) throws IOException { res.setStatus(se.getHttpStatus()); return new SampleErrorList(se.getErrors()); }
It is also possible to set the HTTP status code using an annotation, but in this example the exception determines this, so the handler sets it programmatically.
See here for a downloadable working sample.
REST Web Service Spring Error Handling