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
master
Rossen Stoyanchev 12 years ago
parent a1b7a314c1
commit 67a05e4185
  1. 93
      src/reference/docbook/mvc.xml

@ -3694,16 +3694,21 @@ public class SimpleController {
and invokes <interfacename>@ExceptionHandler</interfacename> methods.</para></note> and invokes <interfacename>@ExceptionHandler</interfacename> methods.</para></note>
</section> </section>
<section id="mvc-ann-rest-handler-exception-resolvers"> <section id="mvc-ann-rest-spring-mvc-exceptions">
<title><classname>DefaultHandlerExceptionResolver</classname> <title>Handling of Spring MVC Exceptions</title>
and <classname>ResponseStatusExceptionResolver</classname></title>
<para>Spring MVC may raise a number of exceptions while processing a request.
<para>By default, the <classname>DispatcherServlet</classname> registers A <classname>SimpleMappingExceptionResolver</classname> can be used to easily
the <classname>DefaultHandlerExceptionResolver</classname>. This map any exception to a default error view or to more specific error views if
resolver handles certain standard Spring MVC exceptions by setting a desired. However when responding to programmatic clients you may prefer to
specific response status code. This is useful when responding to programmatic translate specific exceptions to the appropriate status that indicates a
clients (e.g. Ajax, non-browser) in which the client uses the response code client error (4xx) or a server error (5xx).</para>
to interpret the result.
<para>For this reason Spring MVC provides the
<classname>DefaultHandlerExceptionResolver</classname>, which translates specific
Spring MVC exceptions by setting a specific response status code. By default,
this resolver is registered by the <classname>DispatcherServlet</classname>.
The following table describes some of the exceptions it handles:
<informaltable> <informaltable>
<tgroup cols="2"> <tgroup cols="2">
<thead> <thead>
@ -3715,6 +3720,12 @@ public class SimpleController {
</thead> </thead>
<tbody> <tbody>
<row>
<entry><classname>BindException</classname></entry>
<entry>400 (Bad Request)</entry>
</row>
<row> <row>
<entry><classname>ConversionNotSupportedException</classname></entry> <entry><classname>ConversionNotSupportedException</classname></entry>
@ -3751,12 +3762,24 @@ public class SimpleController {
<entry>405 (Method Not Allowed)</entry> <entry>405 (Method Not Allowed)</entry>
</row> </row>
<row>
<entry><classname>MethodArgumentNotValidException</classname></entry>
<entry>400 (Bad Request)</entry>
</row>
<row> <row>
<entry><classname>MissingServletRequestParameterException</classname></entry> <entry><classname>MissingServletRequestParameterException</classname></entry>
<entry>400 (Bad Request)</entry> <entry>400 (Bad Request)</entry>
</row> </row>
<row>
<entry><classname>MissingServletRequestPartException</classname></entry>
<entry>400 (Bad Request)</entry>
</row>
<row> <row>
<entry><classname>NoSuchRequestHandlingMethodException</classname></entry> <entry><classname>NoSuchRequestHandlingMethodException</classname></entry>
@ -3773,19 +3796,53 @@ public class SimpleController {
</informaltable> </informaltable>
</para> </para>
<para>The <classname>DispatcherServlet</classname> also registers the <note><para>If you explicitly register one or more
<classname>ResponseStatusExceptionResolver</classname>, which handles
exceptions annotated with <interfacename>@ResponseStatus</interfacename>
by setting the response status code to that indicated in the annotation.
Once again this is useful in scenarios with programmatic clients.</para>
<para>Note however that if you explicitly register one or more
<interfacename>HandlerExceptionResolver</interfacename> instances in your configuration <interfacename>HandlerExceptionResolver</interfacename> instances in your configuration
then the defaults registered by the <classname>DispatcherServlet</classname> are then the defaults registered by the <classname>DispatcherServlet</classname> are
cancelled. This is standard behavior with regards to cancelled. This is standard behavior with regards to
<classname>DispatcherServlet</classname> defaults. <classname>DispatcherServlet</classname> defaults.
See <xref linkend="mvc-servlet-special-bean-types"/> for more details.</para> See <xref linkend="mvc-servlet-special-bean-types"/> for more details.</para></note>
<para>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 <classname>DefaultHandlerExceptionResolver</classname>
only sets the status code and doesn't assume how or what content should be written
to the body.</para>
<para>Instead you can create an <interfacename>@ExceptionResolver</interfacename>
class that handles each of the exceptions handled by the
<classname>DefaultHandlerExceptionResolver</classname> 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:</para>
<programlisting language="java">@ExceptionResolver
public class ApplicationExceptionResolver {
@ExceptionHandler
public ResponseEntity handleMediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException ex) {
MyApiError error = ... ;
return new ResponseEntity(error, HttpStatus.SC_NOT_ACCEPTABLE);
}
// more @ExceptionHandler methods ...
}</programlisting>
</section>
<section id="mvc-ann-annotated-exceptions">
<title>Annotating Business Exceptions With <interfacename>@ResponseStatus</interfacename></title>
<para>A business exception can be annotated with
<interfacename>@ResponseStatus</interfacename>. When the exception is raised,
the <classname>ResponseStatusExceptionResolver</classname> handles it by
setting the status of the response accordingly.
By default the <classname>DispatcherServlet</classname> registers
the <classname>ResponseStatusExceptionResolver</classname> and it is
available for use.</para>
</section> </section>
</section> </section>
<section id="mvc-coc"> <section id="mvc-coc">

Loading…
Cancel
Save