Skip to content

Commit 67a05e4

Browse files
committed
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
1 parent a1b7a31 commit 67a05e4

File tree

1 file changed

+75
-18
lines changed

1 file changed

+75
-18
lines changed

src/reference/docbook/mvc.xml

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3694,16 +3694,21 @@ public class SimpleController {
36943694
and invokes <interfacename>@ExceptionHandler</interfacename> methods.</para></note>
36953695
</section>
36963696

3697-
<section id="mvc-ann-rest-handler-exception-resolvers">
3698-
<title><classname>DefaultHandlerExceptionResolver</classname>
3699-
and <classname>ResponseStatusExceptionResolver</classname></title>
3700-
3701-
<para>By default, the <classname>DispatcherServlet</classname> registers
3702-
the <classname>DefaultHandlerExceptionResolver</classname>. This
3703-
resolver handles certain standard Spring MVC exceptions by setting a
3704-
specific response status code. This is useful when responding to programmatic
3705-
clients (e.g. Ajax, non-browser) in which the client uses the response code
3706-
to interpret the result.
3697+
<section id="mvc-ann-rest-spring-mvc-exceptions">
3698+
<title>Handling of Spring MVC Exceptions</title>
3699+
3700+
<para>Spring MVC may raise a number of exceptions while processing a request.
3701+
A <classname>SimpleMappingExceptionResolver</classname> can be used to easily
3702+
map any exception to a default error view or to more specific error views if
3703+
desired. However when responding to programmatic clients you may prefer to
3704+
translate specific exceptions to the appropriate status that indicates a
3705+
client error (4xx) or a server error (5xx).</para>
3706+
3707+
<para>For this reason Spring MVC provides the
3708+
<classname>DefaultHandlerExceptionResolver</classname>, which translates specific
3709+
Spring MVC exceptions by setting a specific response status code. By default,
3710+
this resolver is registered by the <classname>DispatcherServlet</classname>.
3711+
The following table describes some of the exceptions it handles:
37073712
<informaltable>
37083713
<tgroup cols="2">
37093714
<thead>
@@ -3715,6 +3720,12 @@ public class SimpleController {
37153720
</thead>
37163721

37173722
<tbody>
3723+
<row>
3724+
<entry><classname>BindException</classname></entry>
3725+
3726+
<entry>400 (Bad Request)</entry>
3727+
</row>
3728+
37183729
<row>
37193730
<entry><classname>ConversionNotSupportedException</classname></entry>
37203731

@@ -3751,12 +3762,24 @@ public class SimpleController {
37513762
<entry>405 (Method Not Allowed)</entry>
37523763
</row>
37533764

3765+
<row>
3766+
<entry><classname>MethodArgumentNotValidException</classname></entry>
3767+
3768+
<entry>400 (Bad Request)</entry>
3769+
</row>
3770+
37543771
<row>
37553772
<entry><classname>MissingServletRequestParameterException</classname></entry>
37563773

37573774
<entry>400 (Bad Request)</entry>
37583775
</row>
37593776

3777+
<row>
3778+
<entry><classname>MissingServletRequestPartException</classname></entry>
3779+
3780+
<entry>400 (Bad Request)</entry>
3781+
</row>
3782+
37603783
<row>
37613784
<entry><classname>NoSuchRequestHandlingMethodException</classname></entry>
37623785

@@ -3773,19 +3796,53 @@ public class SimpleController {
37733796
</informaltable>
37743797
</para>
37753798

3776-
<para>The <classname>DispatcherServlet</classname> also registers the
3777-
<classname>ResponseStatusExceptionResolver</classname>, which handles
3778-
exceptions annotated with <interfacename>@ResponseStatus</interfacename>
3779-
by setting the response status code to that indicated in the annotation.
3780-
Once again this is useful in scenarios with programmatic clients.</para>
3781-
3782-
<para>Note however that if you explicitly register one or more
3799+
<note><para>If you explicitly register one or more
37833800
<interfacename>HandlerExceptionResolver</interfacename> instances in your configuration
37843801
then the defaults registered by the <classname>DispatcherServlet</classname> are
37853802
cancelled. This is standard behavior with regards to
37863803
<classname>DispatcherServlet</classname> defaults.
3787-
See <xref linkend="mvc-servlet-special-bean-types"/> for more details.</para>
3804+
See <xref linkend="mvc-servlet-special-bean-types"/> for more details.</para></note>
3805+
3806+
<para>If building a REST API, then it's very likely you will want to
3807+
write some additional information about the error to the body of the response
3808+
consistent with the API's error handling throughout. This includes the handling of
3809+
Spring MVC exceptions, for which the <classname>DefaultHandlerExceptionResolver</classname>
3810+
only sets the status code and doesn't assume how or what content should be written
3811+
to the body.</para>
3812+
3813+
<para>Instead you can create an <interfacename>@ExceptionResolver</interfacename>
3814+
class that handles each of the exceptions handled by the
3815+
<classname>DefaultHandlerExceptionResolver</classname> while also writing
3816+
developer-friendly API error information to the response body consistent with
3817+
the rest of all API error handling of the application. For example:</para>
3818+
3819+
<programlisting language="java">@ExceptionResolver
3820+
public class ApplicationExceptionResolver {
3821+
3822+
@ExceptionHandler
3823+
public ResponseEntity handleMediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException ex) {
3824+
MyApiError error = ... ;
3825+
return new ResponseEntity(error, HttpStatus.SC_NOT_ACCEPTABLE);
3826+
}
3827+
3828+
// more @ExceptionHandler methods ...
3829+
3830+
}</programlisting>
3831+
</section>
3832+
3833+
<section id="mvc-ann-annotated-exceptions">
3834+
<title>Annotating Business Exceptions With <interfacename>@ResponseStatus</interfacename></title>
3835+
3836+
<para>A business exception can be annotated with
3837+
<interfacename>@ResponseStatus</interfacename>. When the exception is raised,
3838+
the <classname>ResponseStatusExceptionResolver</classname> handles it by
3839+
setting the status of the response accordingly.
3840+
By default the <classname>DispatcherServlet</classname> registers
3841+
the <classname>ResponseStatusExceptionResolver</classname> and it is
3842+
available for use.</para>
3843+
37883844
</section>
3845+
37893846
</section>
37903847

37913848
<section id="mvc-coc">

0 commit comments

Comments
 (0)