diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java
index c1479df2a78..8211d2ceee9 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java
@@ -87,53 +87,54 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
*
*
This class registers the following {@link HandlerMapping}s:
*
- * - {@link RequestMappingHandlerMapping}
- * ordered at 0 for mapping requests to annotated controller methods.
- *
- {@link HandlerMapping}
- * ordered at 1 to map URL paths directly to view names.
- *
- {@link BeanNameUrlHandlerMapping}
- * ordered at 2 to map URL paths to controller bean names.
- *
- {@link HandlerMapping}
- * ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
- *
- {@link HandlerMapping}
- * ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
+ *
- {@link RequestMappingHandlerMapping}
+ * ordered at 0 for mapping requests to annotated controller methods.
+ *
- {@link HandlerMapping}
+ * ordered at 1 to map URL paths directly to view names.
+ *
- {@link BeanNameUrlHandlerMapping}
+ * ordered at 2 to map URL paths to controller bean names.
+ *
- {@link HandlerMapping}
+ * ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
+ *
- {@link HandlerMapping}
+ * ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
*
*
* Registers these {@link HandlerAdapter}s:
*
- * - {@link RequestMappingHandlerAdapter}
- * for processing requests with annotated controller methods.
- *
- {@link HttpRequestHandlerAdapter}
- * for processing requests with {@link HttpRequestHandler}s.
- *
- {@link SimpleControllerHandlerAdapter}
- * for processing requests with interface-based {@link Controller}s.
+ *
- {@link RequestMappingHandlerAdapter}
+ * for processing requests with annotated controller methods.
+ *
- {@link HttpRequestHandlerAdapter}
+ * for processing requests with {@link HttpRequestHandler}s.
+ *
- {@link SimpleControllerHandlerAdapter}
+ * for processing requests with interface-based {@link Controller}s.
*
*
* Registers a {@link HandlerExceptionResolverComposite} with this chain of
* exception resolvers:
*
- * - {@link ExceptionHandlerExceptionResolver} for handling exceptions
- * through @{@link ExceptionHandler} methods.
- *
- {@link ResponseStatusExceptionResolver} for exceptions annotated
- * with @{@link ResponseStatus}.
- *
- {@link DefaultHandlerExceptionResolver} for resolving known Spring
- * exception types
+ *
- {@link ExceptionHandlerExceptionResolver} for handling exceptions
+ * through @{@link ExceptionHandler} methods.
+ *
- {@link ResponseStatusExceptionResolver} for exceptions annotated
+ * with @{@link ResponseStatus}.
+ *
- {@link DefaultHandlerExceptionResolver} for resolving known Spring
+ * exception types
*
*
* Both the {@link RequestMappingHandlerAdapter} and the
* {@link ExceptionHandlerExceptionResolver} are configured with default
* instances of the following by default:
*
- * - A {@link ContentNegotiationManager}
- *
- A {@link DefaultFormattingConversionService}
- *
- A {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}
- * if a JSR-303 implementation is available on the classpath
- *
- A range of {@link HttpMessageConverter}s depending on the 3rd party
- * libraries available on the classpath.
+ *
- a {@link ContentNegotiationManager}
+ *
- a {@link DefaultFormattingConversionService}
+ *
- a {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}
+ * if a JSR-303 implementation is available on the classpath
+ *
- a range of {@link HttpMessageConverter}s depending on the third-party
+ * libraries available on the classpath.
*
*
* @author Rossen Stoyanchev
* @author Brian Clozel
+ * @author Sebastien Deleuze
* @since 3.1
* @see EnableWebMvc
* @see WebMvcConfigurer
@@ -373,9 +374,9 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
* through annotated controller methods. Consider overriding one of these
* other more fine-grained methods:
*
- * - {@link #addArgumentResolvers} for adding custom argument resolvers.
- *
- {@link #addReturnValueHandlers} for adding custom return value handlers.
- *
- {@link #configureMessageConverters} for adding custom message converters.
+ *
- {@link #addArgumentResolvers} for adding custom argument resolvers.
+ *
- {@link #addReturnValueHandlers} for adding custom return value handlers.
+ *
- {@link #configureMessageConverters} for adding custom message converters.
*
*/
@Bean
@@ -653,23 +654,26 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
* A method available to subclasses for adding default {@link HandlerExceptionResolver}s.
* Adds the following exception resolvers:
*
- * - {@link ExceptionHandlerExceptionResolver}
- * for handling exceptions through @{@link ExceptionHandler} methods.
- *
- {@link ResponseStatusExceptionResolver}
- * for exceptions annotated with @{@link ResponseStatus}.
- *
- {@link DefaultHandlerExceptionResolver}
- * for resolving known Spring exception types
+ *
- {@link ExceptionHandlerExceptionResolver}
+ * for handling exceptions through @{@link ExceptionHandler} methods.
+ *
- {@link ResponseStatusExceptionResolver}
+ * for exceptions annotated with @{@link ResponseStatus}.
+ *
- {@link DefaultHandlerExceptionResolver}
+ * for resolving known Spring exception types
*
*/
protected final void addDefaultHandlerExceptionResolvers(List exceptionResolvers) {
ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver = new ExceptionHandlerExceptionResolver();
- exceptionHandlerExceptionResolver.setApplicationContext(this.applicationContext);
exceptionHandlerExceptionResolver.setContentNegotiationManager(mvcContentNegotiationManager());
exceptionHandlerExceptionResolver.setMessageConverters(getMessageConverters());
+ exceptionHandlerExceptionResolver.setApplicationContext(this.applicationContext);
exceptionHandlerExceptionResolver.afterPropertiesSet();
-
exceptionResolvers.add(exceptionHandlerExceptionResolver);
- exceptionResolvers.add(new ResponseStatusExceptionResolver());
+
+ ResponseStatusExceptionResolver responseStatusExceptionResolver = new ResponseStatusExceptionResolver();
+ responseStatusExceptionResolver.setMessageSource(this.applicationContext);
+ exceptionResolvers.add(responseStatusExceptionResolver);
+
exceptionResolvers.add(new DefaultHandlerExceptionResolver());
}
diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java
index 942d58e160a..38c355e8cfa 100644
--- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java
+++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java
@@ -17,28 +17,35 @@
package org.springframework.web.servlet.config.annotation;
import java.util.List;
+import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
+import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.context.support.StaticMessageSource;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpStatus;
import org.springframework.mock.web.test.MockHttpServletRequest;
+import org.springframework.mock.web.test.MockHttpServletResponse;
import org.springframework.mock.web.test.MockServletContext;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
@@ -63,6 +70,7 @@ import static org.junit.Assert.*;
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
+ * @author Sebastien Deleuze
*/
public class WebMvcConfigurationSupportTests {
@@ -169,10 +177,9 @@ public class WebMvcConfigurationSupportTests {
@Test
public void handlerExceptionResolver() throws Exception {
HandlerExceptionResolverComposite compositeResolver =
- this.wac.getBean("handlerExceptionResolver", HandlerExceptionResolverComposite.class);
+ this.wac.getBean("handlerExceptionResolver", HandlerExceptionResolverComposite.class);
assertEquals(0, compositeResolver.getOrder());
-
List expectedResolvers = compositeResolver.getExceptionResolvers();
assertEquals(ExceptionHandlerExceptionResolver.class, expectedResolvers.get(0).getClass());
@@ -181,6 +188,18 @@ public class WebMvcConfigurationSupportTests {
ExceptionHandlerExceptionResolver eher = (ExceptionHandlerExceptionResolver) expectedResolvers.get(0);
assertNotNull(eher.getApplicationContext());
+
+ LocaleContextHolder.setLocale(Locale.ENGLISH);
+ try {
+ ResponseStatusExceptionResolver rser = (ResponseStatusExceptionResolver) expectedResolvers.get(1);
+ MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ rser.resolveException(request, response, this.wac.getBean(TestController.class), new UserAlreadyExistsException());
+ assertEquals("User already exists!", response.getErrorMessage());
+ }
+ finally {
+ LocaleContextHolder.resetLocaleContext();
+ }
}
@@ -192,6 +211,13 @@ public class WebMvcConfigurationSupportTests {
public TestController testController() {
return new TestController();
}
+
+ @Bean
+ public MessageSource messageSource() {
+ StaticMessageSource messageSource = new StaticMessageSource();
+ messageSource.addMessage("exception.user.exists", Locale.ENGLISH, "User already exists!");
+ return messageSource;
+ }
}
@@ -229,4 +255,9 @@ public class WebMvcConfigurationSupportTests {
}
}
+
+ @ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "exception.user.exists")
+ public static class UserAlreadyExistsException extends RuntimeException {
+ }
+
}