Skip to content

Commit d473506

Browse files
committed
Explicit notes on ExceptionHandler root vs cause resolution
Issue: SPR-16074 (cherry picked from commit ea00c7c)
1 parent 6f65b63 commit d473506

File tree

3 files changed

+25
-18
lines changed

3 files changed

+25
-18
lines changed

spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.springframework.core.annotation.AliasFor;
2727
import org.springframework.stereotype.Component;
2828

29-
3029
/**
3130
* Specialization of {@link Component @Component} for classes that declare
3231
* {@link ExceptionHandler @ExceptionHandler}, {@link InitBinder @InitBinder}, or
@@ -39,10 +38,17 @@
3938
* AnnotationAwareOrderComparator}, i.e. based on
4039
* {@link org.springframework.core.annotation.Order @Order} and
4140
* {@link org.springframework.core.Ordered Ordered}, and applied in that order
42-
* at runtime. For handling exceptions the first {@code @ExceptionHandler} to
43-
* match the exception is used. For model attributes and {@code InitBinder}
44-
* initialization, {@code @ModelAttribute} and {@code @InitBinder} methods will
45-
* also follow {@code @ControllerAdvice} order.
41+
* at runtime. For handling exceptions, an {@code @ExceptionHandler} will be
42+
* picked on the first advice with a matching exception handler method. For
43+
* model attributes and {@code InitBinder} initialization, {@code @ModelAttribute}
44+
* and {@code @InitBinder} methods will also follow {@code @ControllerAdvice} order.
45+
*
46+
* <p>Note: For {@code @ExceptionHandler} methods, a root exception match will be
47+
* preferred to just matching a cause of the current exception, among the handler
48+
* methods of a particular advice bean. However, a cause match on a higher-priority
49+
* advice will still be preferred to a any match (whether root or cause level)
50+
* on a lower-priority advice bean. As a consequence, please declare your primary
51+
* root exception mappings on a prioritized advice bean with a corresponding order!
4652
*
4753
* <p>By default the methods in an {@code @ControllerAdvice} apply globally to
4854
* all Controllers. Use selectors {@link #annotations()},

src/asciidoc/web-mvc.adoc

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,6 @@ Portlet facilities.
484484

485485
[TIP]
486486
====
487-
488487
Available in the https://github.com/spring-projects/[spring-projects Org on Github],
489488
a number of web applications leverage the annotation support described in this section
490489
including __MvcShowcase__, __MvcAjax__, __MvcBasic__, __PetClinic__, __PetCare__,
@@ -800,7 +799,6 @@ the value of `ownerId` is `fred`.
800799

801800
[TIP]
802801
====
803-
804802
To process the @PathVariable annotation, Spring MVC needs to find the matching URI
805803
template variable by name. You can specify it in the annotation:
806804
@@ -1098,7 +1096,6 @@ default it is set to `true`.
10981096

10991097
[TIP]
11001098
====
1101-
11021099
The MVC Java config and the MVC namespace both provide options for enabling the use of
11031100
matrix variables.
11041101
@@ -1151,7 +1148,6 @@ using constants provided in `MediaType` such as `APPLICATION_JSON_VALUE` and
11511148

11521149
[TIP]
11531150
====
1154-
11551151
The __consumes__ condition is supported on the type and on the method level. Unlike most
11561152
other conditions, when used at the type level, method-level consumable types override
11571153
rather than extend type-level consumable types.
@@ -1239,7 +1235,6 @@ specific request header value:
12391235

12401236
[TIP]
12411237
====
1242-
12431238
Although you can match to __Content-Type__ and __Accept__ header values using media type
12441239
wild cards (for example __"content-type=text/*"__ will match to __"text/plain"__ and
12451240
__"text/html"__), it is recommended to use the __consumes__ and __produces__ conditions
@@ -1697,7 +1692,6 @@ for more details.
16971692

16981693
[TIP]
16991694
====
1700-
17011695
What happens when a model attribute name is not explicitly specified? In such cases a
17021696
default name is assigned to the model attribute based on its type. For example if the
17031697
method returns an object of type `Account`, the default name used is "account". You can
@@ -2468,7 +2462,7 @@ the response.
24682462
[[mvc-ann-async-sse]]
24692463
==== HTTP Streaming With Server-Sent Events
24702464

2471-
`SseEmitter` is a sub-class of `ResponseBodyEmitter` providing support for
2465+
`SseEmitter` is a subclass of `ResponseBodyEmitter` providing support for
24722466
http://www.w3.org/TR/eventsource/[Server-Sent Events].
24732467
Server-sent events is a just another variation on the same "HTTP Streaming"
24742468
technique except events pushed from the server are formatted according to
@@ -2752,7 +2746,6 @@ extend the `HandlerInterceptor` interface.
27522746

27532747
[TIP]
27542748
====
2755-
27562749
In the example above, the configured interceptor will apply to all requests handled with
27572750
annotated controller methods. If you want to narrow down the URL paths to which an
27582751
interceptor applies, you can use the MVC namespace or the MVC Java config, or declare
@@ -2768,6 +2761,7 @@ directly on `RequestMappingHandlerAdapter`.
27682761

27692762

27702763

2764+
27712765
[[mvc-viewresolver]]
27722766
== Resolving views
27732767
All MVC frameworks for web applications provide a way to address views. Spring provides
@@ -3271,7 +3265,7 @@ You can also expand and encode using individual URI components:
32713265
.encode();
32723266
----
32733267

3274-
In a Servlet environment the `ServletUriComponentsBuilder` sub-class provides static
3268+
In a Servlet environment the `ServletUriComponentsBuilder` subclass provides static
32753269
factory methods to copy available URL information from a Servlet requests:
32763270

32773271
[source,java,indent=0]
@@ -3971,7 +3965,7 @@ error content to the body of the response.
39713965

39723966
You can do that with `@ExceptionHandler` methods. When declared within a controller such
39733967
methods apply to exceptions raised by `@RequestMapping` methods of that controller (or
3974-
any of its sub-classes). You can also declare an `@ExceptionHandler` method within an
3968+
any of its subclasses). You can also declare an `@ExceptionHandler` method within an
39753969
`@ControllerAdvice` class in which case it handles exceptions from `@RequestMapping`
39763970
methods from many controllers. Below is an example of a controller-local
39773971
`@ExceptionHandler` method:
@@ -3998,6 +3992,16 @@ is thrown that matches one of the types in the list, then the method annotated w
39983992
matching `@ExceptionHandler` will be invoked. If the annotation value is not set then
39993993
the exception types listed as method arguments are used.
40003994

3995+
[TIP]
3996+
====
3997+
For `@ExceptionHandler` methods, a root exception match will be preferred to just
3998+
matching a cause of the current exception, among the handler methods of a particular
3999+
controller or advice bean. However, a cause match on a higher-priority `@ControllerAdvice`
4000+
will still be preferred to a any match (whether root or cause level) on a lower-priority
4001+
advice bean. As a consequence, when using a multi-advice arrangement, please declare your
4002+
primary root exception mappings on a prioritized advice bean with a corresponding order!
4003+
====
4004+
40014005
Much like standard controller methods annotated with a `@RequestMapping` annotation, the
40024006
method arguments and return values of `@ExceptionHandler` methods can be flexible. For
40034007
example, the `HttpServletRequest` can be accessed in Servlet environments and the
@@ -4393,12 +4397,10 @@ then resolved into the `/WEB-INF/jsp/registration.jsp` view by the
43934397

43944398
[TIP]
43954399
====
4396-
43974400
You do not need to define a `DefaultRequestToViewNameTranslator` bean explicitly. If you
43984401
like the default settings of the `DefaultRequestToViewNameTranslator`, you can rely on
43994402
the Spring Web MVC `DispatcherServlet` to instantiate an instance of this class if one
44004403
is not explicitly configured.
4401-
44024404
====
44034405

44044406
Of course, if you need to change the default settings, then you do need to configure

src/asciidoc/web-portlet.adoc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,6 @@ parameters.
11211121

11221122
[TIP]
11231123
====
1124-
11251124
`@RequestMapping` at the type level may be used for plain implementations of the
11261125
`Controller` interface as well. In this case, the request processing code would follow
11271126
the traditional `handle(Action|Render)Request` signature, while the controller's mapping

0 commit comments

Comments
 (0)