From 67a05e41859d1c9ba5df89e041923ab15018239d Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 10 Jul 2012 19:13:10 -0400 Subject: [PATCH] Update section on exception handling MVC chapter Update section on exception handling in Spring MVC chapter to include more guidance on exception handling when implementing a REST API. Issue: SPR-9290 --- src/reference/docbook/mvc.xml | 93 ++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/src/reference/docbook/mvc.xml b/src/reference/docbook/mvc.xml index e739e677ec..ff0299fb31 100644 --- a/src/reference/docbook/mvc.xml +++ b/src/reference/docbook/mvc.xml @@ -3694,16 +3694,21 @@ public class SimpleController { and invokes @ExceptionHandler methods. -
- <classname>DefaultHandlerExceptionResolver</classname> - and <classname>ResponseStatusExceptionResolver</classname> - - By default, the DispatcherServlet registers - the DefaultHandlerExceptionResolver. This - resolver handles certain standard Spring MVC exceptions by setting a - specific response status code. This is useful when responding to programmatic - clients (e.g. Ajax, non-browser) in which the client uses the response code - to interpret the result. +
+ Handling of Spring MVC Exceptions + + Spring MVC may raise a number of exceptions while processing a request. + A SimpleMappingExceptionResolver can be used to easily + map any exception to a default error view or to more specific error views if + desired. However when responding to programmatic clients you may prefer to + translate specific exceptions to the appropriate status that indicates a + client error (4xx) or a server error (5xx). + + For this reason Spring MVC provides the + DefaultHandlerExceptionResolver, which translates specific + Spring MVC exceptions by setting a specific response status code. By default, + this resolver is registered by the DispatcherServlet. + The following table describes some of the exceptions it handles: @@ -3715,6 +3720,12 @@ public class SimpleController { + + BindException + + 400 (Bad Request) + + ConversionNotSupportedException @@ -3751,12 +3762,24 @@ public class SimpleController { 405 (Method Not Allowed) + + MethodArgumentNotValidException + + 400 (Bad Request) + + MissingServletRequestParameterException 400 (Bad Request) + + MissingServletRequestPartException + + 400 (Bad Request) + + NoSuchRequestHandlingMethodException @@ -3773,19 +3796,53 @@ public class SimpleController { - The DispatcherServlet also registers the - ResponseStatusExceptionResolver, which handles - exceptions annotated with @ResponseStatus - by setting the response status code to that indicated in the annotation. - Once again this is useful in scenarios with programmatic clients. - - Note however that if you explicitly register one or more + If you explicitly register one or more HandlerExceptionResolver instances in your configuration then the defaults registered by the DispatcherServlet are cancelled. This is standard behavior with regards to DispatcherServlet defaults. - See for more details. + See for more details. + + If building a REST API, then it's very likely you will want to + write some additional information about the error to the body of the response + consistent with the API's error handling throughout. This includes the handling of + Spring MVC exceptions, for which the DefaultHandlerExceptionResolver + only sets the status code and doesn't assume how or what content should be written + to the body. + + Instead you can create an @ExceptionResolver + class that handles each of the exceptions handled by the + DefaultHandlerExceptionResolver while also writing + developer-friendly API error information to the response body consistent with + the rest of all API error handling of the application. For example: + + @ExceptionResolver +public class ApplicationExceptionResolver { + + @ExceptionHandler + public ResponseEntity handleMediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException ex) { + MyApiError error = ... ; + return new ResponseEntity(error, HttpStatus.SC_NOT_ACCEPTABLE); + } + + // more @ExceptionHandler methods ... + +} +
+ +
+ Annotating Business Exceptions With <interfacename>@ResponseStatus</interfacename> + + A business exception can be annotated with + @ResponseStatus. When the exception is raised, + the ResponseStatusExceptionResolver handles it by + setting the status of the response accordingly. + By default the DispatcherServlet registers + the ResponseStatusExceptionResolver and it is + available for use. +
+