@@ -3694,16 +3694,21 @@ public class SimpleController {
3694
3694
and invokes <interfacename >@ExceptionHandler</interfacename > methods.</para ></note >
3695
3695
</section >
3696
3696
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:
3707
3712
<informaltable >
3708
3713
<tgroup cols =" 2" >
3709
3714
<thead >
@@ -3715,6 +3720,12 @@ public class SimpleController {
3715
3720
</thead >
3716
3721
3717
3722
<tbody >
3723
+ <row >
3724
+ <entry ><classname >BindException</classname ></entry >
3725
+
3726
+ <entry >400 (Bad Request)</entry >
3727
+ </row >
3728
+
3718
3729
<row >
3719
3730
<entry ><classname >ConversionNotSupportedException</classname ></entry >
3720
3731
@@ -3751,12 +3762,24 @@ public class SimpleController {
3751
3762
<entry >405 (Method Not Allowed)</entry >
3752
3763
</row >
3753
3764
3765
+ <row >
3766
+ <entry ><classname >MethodArgumentNotValidException</classname ></entry >
3767
+
3768
+ <entry >400 (Bad Request)</entry >
3769
+ </row >
3770
+
3754
3771
<row >
3755
3772
<entry ><classname >MissingServletRequestParameterException</classname ></entry >
3756
3773
3757
3774
<entry >400 (Bad Request)</entry >
3758
3775
</row >
3759
3776
3777
+ <row >
3778
+ <entry ><classname >MissingServletRequestPartException</classname ></entry >
3779
+
3780
+ <entry >400 (Bad Request)</entry >
3781
+ </row >
3782
+
3760
3783
<row >
3761
3784
<entry ><classname >NoSuchRequestHandlingMethodException</classname ></entry >
3762
3785
@@ -3773,19 +3796,53 @@ public class SimpleController {
3773
3796
</informaltable >
3774
3797
</para >
3775
3798
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
3783
3800
<interfacename >HandlerExceptionResolver</interfacename > instances in your configuration
3784
3801
then the defaults registered by the <classname >DispatcherServlet</classname > are
3785
3802
cancelled. This is standard behavior with regards to
3786
3803
<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
+
3788
3844
</section >
3845
+
3789
3846
</section >
3790
3847
3791
3848
<section id =" mvc-coc" >
0 commit comments