Skip to content

Commit da05b09

Browse files
committed
Polish standard Spring MVC exception handling
Rename ExceptionHandlerSupport to ResponseEntityExceptionHandler and emphasize the contrast to DefaultHandlerExceptionResovler -- i.e. one returns a ResponseEntity and relies on message converters while the other returns a ModelAndView and relies on view resolution. Issue: SPR-9290
1 parent 0a6b116 commit da05b09

File tree

7 files changed

+158
-130
lines changed

7 files changed

+158
-130
lines changed

spring-web/src/main/java/org/springframework/web/HttpRequestMethodNotSupportedException.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@
1717
package org.springframework.web;
1818

1919
import java.util.Collection;
20+
import java.util.HashSet;
21+
import java.util.Set;
22+
2023
import javax.servlet.ServletException;
2124

25+
import org.springframework.http.HttpMethod;
26+
2227
/**
2328
* Exception thrown when a request handler does not support a
2429
* specific request method.
@@ -95,4 +100,15 @@ public String[] getSupportedMethods() {
95100
return this.supportedMethods;
96101
}
97102

103+
/**
104+
* Return the actually supported HTTP methods, if known, as {@link HttpMethod} instances.
105+
*/
106+
public Set<HttpMethod> getSupportedHttpMethods() {
107+
Set<HttpMethod> supportedMethods = new HashSet<HttpMethod>();
108+
for (String value : this.supportedMethods) {
109+
supportedMethods.add(HttpMethod.valueOf(value));
110+
}
111+
return supportedMethods;
112+
}
113+
98114
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
*
3333
* <p>It is typically used to define {@link ExceptionHandler @ExceptionHandler},
3434
* {@link InitBinder @InitBinder}, and {@link ModelAttribute @ModelAttribute}
35-
* methods that apply across controller class hierarchies.
35+
* methods that apply to all {@link RequestMapping @RequestMapping} methods.
3636
*
3737
* @author Rossen Stoyanchev
3838
* @since 3.2
Lines changed: 106 additions & 106 deletions
Large diffs are not rendered by default.

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
* @author Rossen Stoyanchev
6161
* @since 3.0
6262
*
63-
* @see org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerSupport
63+
* @see org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
6464
* @see #handleNoSuchRequestHandlingMethod
6565
* @see #handleHttpRequestMethodNotSupported
6666
* @see #handleHttpMediaTypeNotSupported
Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import static org.junit.Assert.assertEquals;
1919
import static org.junit.Assert.assertTrue;
2020

21-
import java.io.UnsupportedEncodingException;
2221
import java.lang.reflect.Method;
2322
import java.util.Arrays;
2423
import java.util.EnumSet;
@@ -56,13 +55,13 @@
5655
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
5756

5857
/**
59-
* Test fixture for {@link ExceptionHandlerSupport}.
58+
* Test fixture for {@link ResponseEntityExceptionHandler}.
6059
*
6160
* @author Rossen Stoyanchev
6261
*/
63-
public class ExceptionHandlerSupportTests {
62+
public class ResponseEntityExceptionHandlerTests {
6463

65-
private ExceptionHandlerSupport exceptionHandlerSupport;
64+
private ResponseEntityExceptionHandler exceptionHandlerSupport;
6665

6766
private DefaultHandlerExceptionResolver defaultExceptionResolver;
6867

@@ -86,7 +85,7 @@ public void setup() {
8685
@Test
8786
public void supportsAllDefaultHandlerExceptionResolverExceptionTypes() throws Exception {
8887

89-
Method annotMethod = ExceptionHandlerSupport.class.getMethod("handleException", Exception.class, WebRequest.class);
88+
Method annotMethod = ResponseEntityExceptionHandler.class.getMethod("handleException", Exception.class, WebRequest.class);
9089
ExceptionHandler annot = annotMethod.getAnnotation(ExceptionHandler.class);
9190
List<Class<? extends Throwable>> supportedTypes = Arrays.asList(annot.value());
9291

@@ -217,14 +216,14 @@ private static class TestController {
217216
}
218217

219218
@ControllerAdvice
220-
private static class ApplicationExceptionHandler extends ExceptionHandlerSupport {
219+
private static class ApplicationExceptionHandler extends ResponseEntityExceptionHandler {
221220

222221
@Override
223-
protected Object handleServletRequestBindingException(ServletRequestBindingException ex,
222+
protected ResponseEntity<Object> handleServletRequestBindingException(ServletRequestBindingException ex,
224223
HttpHeaders headers, HttpStatus status, WebRequest request) {
225224

226225
headers.set("someHeader", "someHeaderValue");
227-
return "error content";
226+
return handleExceptionInternal(ex, "error content", headers, status, request);
228227
}
229228

230229

src/reference/docbook/mvc.xml

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3843,15 +3843,23 @@ public class SimpleController {
38433843
transparently by setting the status of the response. However, it stops short
38443844
of writing any error content to the body of the response while your
38453845
application may need to add developer-friendly content to every error
3846-
response for example when providing a REST API.</para>
3847-
3848-
<para>To achieve this extend <classname>ExceptionHandlerSupport</classname>,
3849-
a convenient base class with an <interfacename>@ExceptionHandler</interfacename>
3850-
method that handles standard Spring MVC exceptions just as the
3851-
<classname>DefaultHandlerExceptionResolver</classname> does but also
3852-
allowing you to prepare error content for the body of the response.
3853-
See the Javadoc of <classname>ExceptionHandlerSupport</classname>
3854-
for more details.</para>
3846+
response for example when providing a REST API. You can prepare a
3847+
<classname>ModelAndView</classname> and
3848+
render error content through view resolution -- i.e. by configuring a
3849+
<classname>ContentNeogitatingViewResolver</classname>,
3850+
<classname>MappingJacksonJsonView</classname>, and so on. However, you
3851+
may prefer to use <interfacename>@ExceptionHandler</interfacename>
3852+
methods instead.</para>
3853+
3854+
<para>If you prefer to write error content via
3855+
<interfacename>@ExceptionHandler</interfacename> methods you can extend
3856+
<classname>ResponseEntityExceptionHandler</classname> instead.
3857+
This is a convenient base for <interfacename>@ControllerAdvice</interfacename>
3858+
classes providing an <interfacename>@ExceptionHandler</interfacename>
3859+
method to handle standard Spring MVC exceptions and return
3860+
<classname>ResponseEntity</classname>. That allows you to customize the response
3861+
and write error content with message converters. See the Javadoc of
3862+
<classname>ResponseEntityExceptionHandler</classname> for more details.</para>
38553863
</section>
38563864

38573865
<section id="mvc-ann-annotated-exceptions">

src/reference/docbook/new-in-3.2.xml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
</section>
6767

6868
<section id="new-in-3.2-webmvc-controller-advice">
69-
<title><interfacename>@ControllerAdvice</interfacename> annotation</title>
69+
<title>New <interfacename>@ControllerAdvice</interfacename> annotation</title>
7070

7171
<para>Classes annotated with <interfacename>@ControllerAdvice</interfacename>
7272
can contain <interfacename>@ExceptionHandler</interfacename>,
@@ -81,13 +81,18 @@
8181
</section>
8282

8383
<section id="new-in-3.2-webmvc-exception-handler-support">
84-
<title><classname>ExceptionHandlerSupport</classname> class</title>
84+
<title>New <classname>ResponseEntityExceptionHandler</classname> class</title>
8585

8686
<para>A convenient base class with an
8787
<interfacename>@ExceptionHandler</interfacename>
88-
method that handles standard Spring MVC exceptions, just as the
89-
<classname>DefaultHandlerExceptionResolver</classname> does, but also
90-
allowing you to prepare error content for the body of the response.</para>
88+
method that handles standard Spring MVC exceptions and returns a
89+
<classname>ResponseEntity</classname> that allowing customizing and writing
90+
the response with HTTP message converters. This servers as an alternative
91+
to the <classname>DefaultHandlerExceptionResolver</classname>, which does
92+
the same but returns a <classname>ModelAndView</classname> instead.</para>
93+
94+
<para>See the revised <xref linkend="mvc-exceptionhandlers"/>
95+
including information on customizing the default Servlet container error page.</para>
9196

9297
</section>
9398

0 commit comments

Comments
 (0)