Browse Source

Explicit notes on non-null enforcement and deep cause support in 5.3

Closes gh-26296
See gh-26317
pull/26385/head
Juergen Hoeller 5 years ago
parent
commit
be5eb7037f
  1. 5
      spring-web/src/main/java/org/springframework/web/bind/annotation/ExceptionHandler.java
  2. 24
      src/docs/asciidoc/web/webmvc.adoc

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

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,6 +33,9 @@ import java.lang.annotation.Target;
* <li>An exception argument: declared as a general Exception or as a more * <li>An exception argument: declared as a general Exception or as a more
* specific exception. This also serves as a mapping hint if the annotation * specific exception. This also serves as a mapping hint if the annotation
* itself does not narrow the exception types through its {@link #value()}. * itself does not narrow the exception types through its {@link #value()}.
* You may refer to a top-level exception being propagated or to a nested
* cause within a wrapper exception. As of 5.3, any cause level is being
* exposed, whereas previously only an immediate cause was considered.
* <li>Request and/or response objects (typically from the Servlet API). * <li>Request and/or response objects (typically from the Servlet API).
* You may choose any specific request/response type, e.g. * You may choose any specific request/response type, e.g.
* {@link javax.servlet.ServletRequest} / {@link javax.servlet.http.HttpServletRequest}. * {@link javax.servlet.ServletRequest} / {@link javax.servlet.http.HttpServletRequest}.

24
src/docs/asciidoc/web/webmvc.adoc

@ -2222,6 +2222,17 @@ This can be the case for `Long`, `UUID`, and other target types. If you want to
to be injected, either use the `required` flag on the argument annotation, or declare the to be injected, either use the `required` flag on the argument annotation, or declare the
argument as `@Nullable`. argument as `@Nullable`.
[NOTE]
====
As of 5.3, non-null arguments will be enforced even after type conversion. If your handler
method intends to accept a null value as well, either declare your argument as `@Nullable`
or mark it as `required=false` in the corresponding `@RequestParam` etc annotation. This is
a best practice and the recommended solution for regressions encountered in a 5.3 upgrade.
Alternatively, you may specifically handle e.g. the resulting `MissingPathVariableException`
in the case of a required `@PathVariable`. A null value after conversion will be treated like
an empty original value, so the corresponding `Missing...Exception` variants will be thrown.
====
[[mvc-ann-matrix-variables]] [[mvc-ann-matrix-variables]]
@ -3683,14 +3694,15 @@ controller-specific `Formatter` implementations, as the following example shows:
} }
---- ----
The exception may match against a top-level exception being propagated (that is, a direct The exception may match against a top-level exception being propagated (e.g. a direct
`IOException` being thrown) or against the immediate cause within a top-level wrapper exception `IOException` being thrown) or against a nested cause within a wrapper exception (e.g.
(for example, an `IOException` wrapped inside an `IllegalStateException`). an `IOException` wrapped inside an `IllegalStateException`). As of 5.3, this can match
at arbitrary cause levels, whereas previously only an immediate cause was considered.
For matching exception types, preferably declare the target exception as a method argument, For matching exception types, preferably declare the target exception as a method argument,
as the preceding example shows. When multiple exception methods match, a root exception match is generally as the preceding example shows. When multiple exception methods match, a root exception match is
preferred to a cause exception match. More specifically, the `ExceptionDepthComparator` is generally preferred to a cause exception match. More specifically, the `ExceptionDepthComparator`
used to sort exceptions based on their depth from the thrown exception type. is used to sort exceptions based on their depth from the thrown exception type.
Alternatively, the annotation declaration may narrow the exception types to match, Alternatively, the annotation declaration may narrow the exception types to match,
as the following example shows: as the following example shows:

Loading…
Cancel
Save