diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
index 1954b7965e..e4043f4248 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,22 +60,84 @@ import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
*
This exception resolver is enabled by default in the common Spring
* {@link org.springframework.web.servlet.DispatcherServlet}.
*
+ *
+ *
+ * Supported Exceptions
+ *
+ *
+ * Exception |
+ * HTTP Status Code |
+ *
+ *
+ *
+ *
+ * HttpRequestMethodNotSupportedException |
+ * 405 (SC_METHOD_NOT_ALLOWED) |
+ *
+ *
+ * HttpMediaTypeNotSupportedException |
+ * 415 (SC_UNSUPPORTED_MEDIA_TYPE) |
+ *
+ *
+ * HttpMediaTypeNotAcceptableException |
+ * 406 (SC_NOT_ACCEPTABLE) |
+ *
+ *
+ * MissingPathVariableException |
+ * 500 (SC_INTERNAL_SERVER_ERROR) |
+ *
+ *
+ * MissingServletRequestParameterException |
+ * 500 (SC_INTERNAL_SERVER_ERROR) |
+ *
+ *
+ * ServletRequestBindingException |
+ * 400 (SC_BAD_REQUEST) |
+ *
+ *
+ * ConversionNotSupportedException |
+ * 500 (SC_INTERNAL_SERVER_ERROR) |
+ *
+ *
+ * TypeMismatchException |
+ * 400 (SC_BAD_REQUEST) |
+ *
+ *
+ * HttpMessageNotReadableException |
+ * 400 (SC_BAD_REQUEST) |
+ *
+ *
+ * HttpMessageNotWritableException |
+ * 500 (SC_INTERNAL_SERVER_ERROR) |
+ *
+ *
+ * MethodArgumentNotValidException |
+ * 400 (SC_BAD_REQUEST) |
+ *
+ *
+ * MissingServletRequestPartException |
+ * 400 (SC_BAD_REQUEST) |
+ *
+ *
+ * BindException |
+ * 400 (SC_BAD_REQUEST) |
+ *
+ *
+ * NoHandlerFoundException |
+ * 400 (SC_NOT_FOUND) |
+ *
+ *
+ * AsyncRequestTimeoutException |
+ * 503 (SC_SERVICE_UNAVAILABLE) |
+ *
+ *
+ *
+ *
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @since 3.0
* @see org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
- * @see #handleHttpRequestMethodNotSupported
- * @see #handleHttpMediaTypeNotSupported
- * @see #handleMissingServletRequestParameter
- * @see #handleServletRequestBindingException
- * @see #handleTypeMismatch
- * @see #handleHttpMessageNotReadable
- * @see #handleHttpMessageNotWritable
- * @see #handleMethodArgumentNotValidException
- * @see #handleMissingServletRequestParameter
- * @see #handleMissingServletRequestPartException
- * @see #handleBindException
*/
public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java
index 9688eb5060..db00c6d653 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java
@@ -59,7 +59,7 @@ import org.springframework.web.util.UriUtils;
* acceptCharset |
* false |
* true |
- * Specifies the list of character encodings for input data that is accepted
+ * | Specifies the list of character encodings for input data that is accepted
* by the server processing this form. The value is a space- and/or comma-delimited
* list of charset values. The client must interpret this list as an exclusive-or
* list, i.e., the server is able to accept any single character encoding per
@@ -69,7 +69,7 @@ import org.springframework.web.util.UriUtils;
* | action |
* false |
* true |
- * HTML Required Attribute |
+ * HTML Required Attribute |
*
*
* cssClass |
diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc
index 8851748571..a43cccdbc8 100644
--- a/src/docs/asciidoc/web/webmvc.adoc
+++ b/src/docs/asciidoc/web/webmvc.adoc
@@ -506,6 +506,109 @@ declare it as an <> bean or configure it directly on
+[[mvc-exceptionhandlers]]
+=== Exception Resolution
+
+If an exception occurs during the mapping or the invocation of a request handler (e.g. an
+`@Controller`), the `DispatcherServlet` delegates to a chain of `HandlerExceptionResolver`
+beans to try and resolve the exception and to provide alternative handling for it, which
+typically means preparing an error response whether an HTML error page, an error status,
+or both.
+
+The table below lists the available `HandlerExceptionResolver` implementations:
+
+[cols="1,2", options="header"]
+.HandlerExceptionResolver implementations
+|===
+| HandlerExceptionResolver| Description
+
+| `SimpleMappingExceptionResolver`
+| A mapping between exception class names and error view names. Useful for rendering
+error pages in a browser application.
+
+| {api-spring-framework}/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html[DefaultHandlerExceptionResolver]
+| Resolves exceptions raised by Spring MVC and maps them to HTTP status codes.
+
+Also see alternative `ResponseEntityExceptionHandler` and <>.
+
+| `ResponseStatusExceptionResolver`
+| Resolves exceptions with the `@ResponseStatus` annotation and maps them to HTTP status
+codes based on the value in the annotation.
+
+| `ExceptionHandlerExceptionResolver`
+| Resolves exceptions by invoking an `@ExceptionHandler` method in an `@Controller` or an
+`@ControllerAdvice` class. See <>.
+|===
+
+
+[[mvc-excetionhandlers-handling]]
+==== Handling
+
+You chain exception resolvers by declaring more than one exception resolver beans and,
+if necessary, setting the `order` property to specify ordering. Remember, the higher the
+order property, the later the exception resolver is positioned in the chain.
+
+The contract of `HandlerExceptionResolver` specifies that it __can__ return:
+
+* `ModelAndView` that points to an error view.
+* Empty `ModelAndView` if the exception was handled within the resolver.
+* `null` if the exception remains unresolved, for subsequent resolvers to try; if the
+exception remains unresolved by any resolver, it is re-thrown and left to propagate to
+the Servlet container.
+
+To configure exception handling is as simple as adding `HandlerExceptionResolver` beans
+to your Spring configuration. The <> automatically declares built-in
+resolvers for default Spring MVC exceptions, for `@ResponseStatus` annotated exceptions,
+and for support of `@ExceptionHandler` methods. You can customize that list or replace it.
+
+
+[[mvc-ann-customer-servlet-container-error-page]]
+==== Container error page
+
+If an exception remains unresolved by any `HandlerExceptionResolver` and is therefore
+left to propagate, or if the response status is set to an error status (i.e. 4xx, 5xx),
+Servlet containers may render a default error page in HTML. To customize the default
+error page of the container, you can declare an error page mapping in `web.xml`:
+
+[source,xml,indent=0]
+[subs="verbatim,quotes"]
+----
+
+ /error
+
+----
+
+Given the above, when an exception bubbles up, or the response has an error status, the
+Servlet container makes an ERROR dispatch within the container to the configured URL
+(e.g. "/error"). This is then processed by the `DispatcherServlet`, possibly mapping it
+to an `@Controller` which could be implemented to return an error view name with a model
+or to render a JSON response as shown below:
+
+[source,java,indent=0]
+[subs="verbatim,quotes"]
+----
+ @RestController
+ public class ErrorController {
+
+ @RequestMapping(path = "/error")
+ public Map handle(HttpServletRequest request) {
+ Map map = new HashMap();
+ map.put("status", request.getAttribute("javax.servlet.error.status_code"));
+ map.put("reason", request.getAttribute("javax.servlet.error.message"));
+ return map;
+ }
+ }
+----
+
+[TIP]
+====
+The Servlet API does not provide a way to create error page mappings in Java. You can
+however use both an `WebApplicationInitializer` and a minimal `web.xml`.
+====
+
+
+
+
[[mvc-viewresolver]]
=== View Resolution
[.small]#<>#
@@ -515,7 +618,7 @@ models in a browser without tying you to a specific view technology. `ViewResolv
provides a mapping between view names and actual views. `View` addresses the preparation
of data before handing over to a specific view technology.
-This table below provides more details on the `ViewResolver` hierarchy:
+The table below provides more details on the `ViewResolver` hierarchy:
[[mvc-view-resolvers-tbl]]
.ViewResolver implementations
@@ -575,9 +678,9 @@ The contract of a `ViewResolver` specifies that it __can__ return null to indica
view could not be found. However in the case of JSPs, and `InternalResourceViewResolver`,
the only way to figure out if a JSP exists is to perform a dispatch through
`RequestDispatcher`. Therefore an `InternalResourceViewResolver` must always be configured
-to be last in the overal order of view resolvers.
+to be last in the overall order of view resolvers.
-To configure view resolution is as simple as adding a `ViewResolver` beans to your Spring
+To configure view resolution is as simple as adding `ViewResolver` beans to your Spring
configuration. The <> provides provides a dedicated configuration API for
<> and also for adding logic-less
<> which are useful for HTML template
@@ -2666,6 +2769,67 @@ controller-specific ``Formatter``'s:
+[[mvc-ann-exceptionhandler]]
+=== Exception Methods
+
+`@ExceptionHandler` methods in an `@Controller` can be used to handle exceptions during
+request handling from the same controller. An `@ExceptionHandler` can also be declared
+in an <> to apply across controllers.
+Support for `@ExceptionHandler` methods in Spring MVC is provided through the
+<> mechanism.
+
+Below is an example:
+
+[source,java,indent=0]
+[subs="verbatim,quotes"]
+----
+ @Controller
+ public class SimpleController {
+
+ // ...
+
+ @ExceptionHandler(IOException.class)
+ public ResponseEntity handle(IOException ex) {
+ // ...
+ }
+
+ }
+----
+
+The value of the `@ExceptionHandler` annotation can be set to an array of Exception types
+to match to. Or if the annotation value is not set, then the exception type declared in
+the method signature is used instead. `@ExceptionHandler` methods can declare other
+arguments too, e.g. the `HttpServletRequest`. The return value type can be a `String`,
+which is interpreted as a view name, a `ModelAndView` object, a `ResponseEntity`, or you
+can also add the `@ResponseBody` annotation.
+
+For `@ExceptionHandler` methods, a root exception match will be preferred to just
+matching a cause of the current exception, among the handler methods of a particular
+controller or advice bean. However, a cause match on a higher-priority `@ControllerAdvice`
+will still be preferred to a any match (whether root or cause level) on a lower-priority
+advice bean. As a consequence, when using a multi-advice arrangement, please declare your
+primary root exception mappings on a prioritized advice bean with a corresponding order!
+
+[[mvc-ann-rest-exceptions]]
+==== REST API exceptions
+
+A common requirement for REST services is to include error details in the body of the
+response. The Spring Framework does not automatically do this because the representation
+of error details in the response body is application specific. However a
+`@RestController` may use `@ExceptionHandler` methods with a `ResponseEntity` return
+value to set the status and the body of the response. Such methods may also be declared
+in `@ControllerAdvice` classes to apply them globally.
+
+Applications that implement global exception handling with error details in the response
+body should consider extending
+{api-spring-framework}/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.html[ResponseEntityExceptionHandler]
+which provides handling for exceptions that Spring MVC raises along with hooks to
+customize the response body. To make use of this, create a sub-class of
+`ResponseEntityExceptionHandler`, annotate with `@ControllerAdvice`, override the
+necessary methods, and declare it as a Spring bean.
+
+
+
[[mvc-ann-controller-advice]]
=== Controller Advice
[.small]#<>#
@@ -2929,265 +3093,6 @@ in order to use a specific instance of `MvcUriComponentsBuilder` with a custom b
-[[mvc-exceptionhandlers]]
-== Exception Handling
-
-
-
-[[mvc-exceptionhandlers-overview]]
-=== Overview
-
-Spring `HandlerExceptionResolver` implementations deal with unexpected exceptions that
-occur during controller execution. A `HandlerExceptionResolver` somewhat resembles the
-exception mappings you can define in the web application descriptor `web.xml`. However,
-they provide a more flexible way to do so. For example they provide information about
-which handler was executing when the exception was thrown. Furthermore, a programmatic
-way of handling exceptions gives you more options for responding appropriately before
-the request is forwarded to another URL (the same end result as when you use the Servlet
-specific exception mappings).
-
-Besides implementing the `HandlerExceptionResolver` interface, which is only a matter of
-implementing the `resolveException(Exception, Handler)` method and returning a
-`ModelAndView`, you may also use the provided `SimpleMappingExceptionResolver` or create
-`@ExceptionHandler` methods. The `SimpleMappingExceptionResolver` enables you to take
-the class name of any exception that might be thrown and map it to a view name. This is
-functionally equivalent to the exception mapping feature from the Servlet API, but it is
-also possible to implement more finely grained mappings of exceptions from different
-handlers. The `@ExceptionHandler` annotation on the other hand can be used on methods
-that should be invoked to handle an exception. Such methods may be defined locally
-within an `@Controller` or may apply to many `@Controller` classes when defined within an
-`@ControllerAdvice` class. The following sections explain this in more detail.
-
-
-
-[[mvc-ann-exceptionhandler]]
-=== @ExceptionHandler
-
-The `HandlerExceptionResolver` interface and the `SimpleMappingExceptionResolver`
-implementations allow you to map Exceptions to specific views declaratively along with
-some optional Java logic before forwarding to those views. However, in some cases,
-especially when relying on `@ResponseBody` methods rather than on view resolution, it
-may be more convenient to directly set the status of the response and optionally write
-error content to the body of the response.
-
-You can do that with `@ExceptionHandler` methods. When declared within a controller such
-methods apply to exceptions raised by `@RequestMapping` methods of that controller (or
-any of its subclasses). You can also declare an `@ExceptionHandler` method within an
-`@ControllerAdvice` class in which case it handles exceptions from `@RequestMapping`
-methods from many controllers. Below is an example of a controller-local
-`@ExceptionHandler` method:
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
- @Controller
- public class SimpleController {
-
- // @RequestMapping methods omitted ...
-
- @ExceptionHandler(IOException.class)
- public ResponseEntity handleIOException(IOException ex) {
- // prepare responseEntity
- return responseEntity;
- }
-
- }
-----
-
-The `@ExceptionHandler` value can be set to an array of Exception types. If an exception
-is thrown that matches one of the types in the list, then the method annotated with the
-matching `@ExceptionHandler` will be invoked. If the annotation value is not set then
-the exception types listed as method arguments are used.
-
-[TIP]
-====
-For `@ExceptionHandler` methods, a root exception match will be preferred to just
-matching a cause of the current exception, among the handler methods of a particular
-controller or advice bean. However, a cause match on a higher-priority `@ControllerAdvice`
-will still be preferred to a any match (whether root or cause level) on a lower-priority
-advice bean. As a consequence, when using a multi-advice arrangement, please declare your
-primary root exception mappings on a prioritized advice bean with a corresponding order!
-====
-
-Much like standard controller methods annotated with a `@RequestMapping` annotation, the
-method arguments and return values of `@ExceptionHandler` methods can be flexible. For
-example, the `HttpServletRequest` can be accessed in Servlet environments. The return
-type can be a `String`, which is interpreted as a view name, a `ModelAndView` object,
-a `ResponseEntity`, or you can also add the `@ResponseBody` to have the method return
-value converted with message converters and written to the response stream.
-
-
-
-[[mvc-ann-rest-spring-mvc-exceptions]]
-=== Framework exceptions
-
-Spring MVC may raise a number of exceptions while processing a request. The
-`SimpleMappingExceptionResolver` can easily map any exception to a default error view as
-needed. However, when working with clients that interpret responses in an automated way
-you will want to set specific status code on the response. Depending on the exception
-raised the status code may indicate a client error (4xx) or a server error (5xx).
-
-The `DefaultHandlerExceptionResolver` translates Spring MVC exceptions to specific error
-status codes. It is registered by default with the MVC namespace, the MVC Java config,
-and also by the `DispatcherServlet` (i.e. when not using the MVC namespace or Java
-config). Listed below are some of the exceptions handled by this resolver and the
-corresponding status codes:
-
-|===
-| Exception| HTTP Status Code
-
-| `BindException`
-| 400 (Bad Request)
-
-| `ConversionNotSupportedException`
-| 500 (Internal Server Error)
-
-| `HttpMediaTypeNotAcceptableException`
-| 406 (Not Acceptable)
-
-| `HttpMediaTypeNotSupportedException`
-| 415 (Unsupported Media Type)
-
-| `HttpMessageNotReadableException`
-| 400 (Bad Request)
-
-| `HttpMessageNotWritableException`
-| 500 (Internal Server Error)
-
-| `HttpRequestMethodNotSupportedException`
-| 405 (Method Not Allowed)
-
-| `MethodArgumentNotValidException`
-| 400 (Bad Request)
-
-| `MissingPathVariableException`
-| 500 (Internal Server Error)
-
-| `MissingServletRequestParameterException`
-| 400 (Bad Request)
-
-| `MissingServletRequestPartException`
-| 400 (Bad Request)
-
-| `NoHandlerFoundException`
-| 404 (Not Found)
-
-| `NoSuchRequestHandlingMethodException`
-| 404 (Not Found)
-
-| `TypeMismatchException`
-| 400 (Bad Request)
-|===
-
-The `DefaultHandlerExceptionResolver` works transparently by setting the status of the
-response. However, it stops short of writing any error content to the body of the
-response while your application may need to add developer-friendly content to every
-error response for example when providing a REST API. You can prepare a `ModelAndView`
-and render error content through view resolution -- i.e. by configuring a
-`ContentNegotiatingViewResolver`, `MappingJackson2JsonView`, and so on. However, you may
-prefer to use `@ExceptionHandler` methods instead.
-
-If you prefer to write error content via `@ExceptionHandler` methods you can extend
-`ResponseEntityExceptionHandler` instead. This is a convenient base for
-`@ControllerAdvice` classes providing an `@ExceptionHandler` method to handle standard
-Spring MVC exceptions and return `ResponseEntity`. That allows you to customize the
-response and write error content with message converters. See the
-`ResponseEntityExceptionHandler` javadocs for more details.
-
-
-
-[[mvc-ann-rest-exceptions]]
-=== REST API exceptions
-
-An `@RestController` may use `@ExceptionHandler` methods that return a
-`ResponseEntity` to provide both a response status and error details in the body
-of the response. Such methods may also be added to `@ControllerAdvice`
-classes for exception handling across a subset or all controllers.
-
-A common requirement is to include error details in the body of the response.
-Spring does not automatically do this (although Spring Boot does) because the
-representation of error details in the response body is application specific.
-
-Applications that wish to implement a global exception handling strategy with
-error details in the response body should consider extending the abstract base
-class `ResponseEntityExceptionHandler` which provides handling for the exceptions
-that Spring MVC raises and provides hooks to customize the response body as
-well as to handle other exceptions. Simply declare the extension class as a
-Spring bean and annotate it with `@ControllerAdvice`. For more details see
-See `ResponseEntityExceptionHandler`.
-
-
-
-[[mvc-ann-annotated-exceptions]]
-=== Annotated Exception
-
-A business exception can be annotated with `@ResponseStatus`. When the exception is
-raised, the `ResponseStatusExceptionResolver` handles it by setting the status of the
-response accordingly. By default the `DispatcherServlet` registers the
-`ResponseStatusExceptionResolver` and it is available for use.
-
-
-
-[[mvc-ann-customer-servlet-container-error-page]]
-=== Container error page
-
-When the status of the response is set to an error status code and the body of the
-response is empty, Servlet containers commonly render an HTML formatted error page. To
-customize the default error page of the container, you can declare an ``
-element in `web.xml`. Up until Servlet 3, that element had to be mapped to a specific
-status code or exception type. Starting with Servlet 3 an error page does not need to be
-mapped, which effectively means the specified location customizes the default Servlet
-container error page.
-
-[source,xml,indent=0]
-[subs="verbatim,quotes"]
-----
-
- /error
-
-----
-
-Note that the actual location for the error page can be a JSP page or some other URL
-within the container including one handled through an `@Controller` method:
-
-When writing error information, the status code and the error message set on the
-`HttpServletResponse` can be accessed through request attributes in a controller:
-
-[source,java,indent=0]
-[subs="verbatim,quotes"]
-----
- @Controller
- public class ErrorController {
-
- @RequestMapping(path = "/error", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
- @ResponseBody
- public Map handle(HttpServletRequest request) {
-
- Map map = new HashMap();
- map.put("status", request.getAttribute("javax.servlet.error.status_code"));
- map.put("reason", request.getAttribute("javax.servlet.error.message"));
-
- return map;
- }
-
- }
-----
-
-or in a JSP:
-
-[source,xml,indent=0]
-[subs="verbatim,quotes"]
-----
- <%@ page contentType="application/json" pageEncoding="UTF-8"%>
- {
- status:<%=request.getAttribute("javax.servlet.error.status_code") %>,
- reason:<%=request.getAttribute("javax.servlet.error.message") %>
- }
-----
-
-
-
-
[[mvc-ann-async]]
== Async Requests
[.small]#<>#