Set ResponseStatusExceptionResolver.messageSource in the MVC Java config
Issue: SPR-12380
(cherry picked from commit 17b9bde)
This commit is contained in:
@@ -87,53 +87,54 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
|||||||
*
|
*
|
||||||
* <p>This class registers the following {@link HandlerMapping}s:</p>
|
* <p>This class registers the following {@link HandlerMapping}s:</p>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link RequestMappingHandlerMapping}
|
* <li>{@link RequestMappingHandlerMapping}
|
||||||
* ordered at 0 for mapping requests to annotated controller methods.
|
* ordered at 0 for mapping requests to annotated controller methods.
|
||||||
* <li>{@link HandlerMapping}
|
* <li>{@link HandlerMapping}
|
||||||
* ordered at 1 to map URL paths directly to view names.
|
* ordered at 1 to map URL paths directly to view names.
|
||||||
* <li>{@link BeanNameUrlHandlerMapping}
|
* <li>{@link BeanNameUrlHandlerMapping}
|
||||||
* ordered at 2 to map URL paths to controller bean names.
|
* ordered at 2 to map URL paths to controller bean names.
|
||||||
* <li>{@link HandlerMapping}
|
* <li>{@link HandlerMapping}
|
||||||
* ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
|
* ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
|
||||||
* <li>{@link HandlerMapping}
|
* <li>{@link HandlerMapping}
|
||||||
* ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
|
* ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>Registers these {@link HandlerAdapter}s:
|
* <p>Registers these {@link HandlerAdapter}s:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link RequestMappingHandlerAdapter}
|
* <li>{@link RequestMappingHandlerAdapter}
|
||||||
* for processing requests with annotated controller methods.
|
* for processing requests with annotated controller methods.
|
||||||
* <li>{@link HttpRequestHandlerAdapter}
|
* <li>{@link HttpRequestHandlerAdapter}
|
||||||
* for processing requests with {@link HttpRequestHandler}s.
|
* for processing requests with {@link HttpRequestHandler}s.
|
||||||
* <li>{@link SimpleControllerHandlerAdapter}
|
* <li>{@link SimpleControllerHandlerAdapter}
|
||||||
* for processing requests with interface-based {@link Controller}s.
|
* for processing requests with interface-based {@link Controller}s.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>Registers a {@link HandlerExceptionResolverComposite} with this chain of
|
* <p>Registers a {@link HandlerExceptionResolverComposite} with this chain of
|
||||||
* exception resolvers:
|
* exception resolvers:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions
|
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions
|
||||||
* through @{@link ExceptionHandler} methods.
|
* through @{@link ExceptionHandler} methods.
|
||||||
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated
|
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated
|
||||||
* with @{@link ResponseStatus}.
|
* with @{@link ResponseStatus}.
|
||||||
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring
|
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring
|
||||||
* exception types
|
* exception types
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>Both the {@link RequestMappingHandlerAdapter} and the
|
* <p>Both the {@link RequestMappingHandlerAdapter} and the
|
||||||
* {@link ExceptionHandlerExceptionResolver} are configured with default
|
* {@link ExceptionHandlerExceptionResolver} are configured with default
|
||||||
* instances of the following by default:
|
* instances of the following by default:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>A {@link ContentNegotiationManager}
|
* <li>a {@link ContentNegotiationManager}
|
||||||
* <li>A {@link DefaultFormattingConversionService}
|
* <li>a {@link DefaultFormattingConversionService}
|
||||||
* <li>A {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}
|
* <li>a {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}
|
||||||
* if a JSR-303 implementation is available on the classpath
|
* if a JSR-303 implementation is available on the classpath
|
||||||
* <li>A range of {@link HttpMessageConverter}s depending on the 3rd party
|
* <li>a range of {@link HttpMessageConverter}s depending on the third-party
|
||||||
* libraries available on the classpath.
|
* libraries available on the classpath.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @author Brian Clozel
|
* @author Brian Clozel
|
||||||
|
* @author Sebastien Deleuze
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
* @see EnableWebMvc
|
* @see EnableWebMvc
|
||||||
* @see WebMvcConfigurer
|
* @see WebMvcConfigurer
|
||||||
@@ -373,9 +374,9 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
|||||||
* through annotated controller methods. Consider overriding one of these
|
* through annotated controller methods. Consider overriding one of these
|
||||||
* other more fine-grained methods:
|
* other more fine-grained methods:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link #addArgumentResolvers} for adding custom argument resolvers.
|
* <li>{@link #addArgumentResolvers} for adding custom argument resolvers.
|
||||||
* <li>{@link #addReturnValueHandlers} for adding custom return value handlers.
|
* <li>{@link #addReturnValueHandlers} for adding custom return value handlers.
|
||||||
* <li>{@link #configureMessageConverters} for adding custom message converters.
|
* <li>{@link #configureMessageConverters} for adding custom message converters.
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -653,23 +654,26 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
|||||||
* A method available to subclasses for adding default {@link HandlerExceptionResolver}s.
|
* A method available to subclasses for adding default {@link HandlerExceptionResolver}s.
|
||||||
* <p>Adds the following exception resolvers:
|
* <p>Adds the following exception resolvers:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link ExceptionHandlerExceptionResolver}
|
* <li>{@link ExceptionHandlerExceptionResolver}
|
||||||
* for handling exceptions through @{@link ExceptionHandler} methods.
|
* for handling exceptions through @{@link ExceptionHandler} methods.
|
||||||
* <li>{@link ResponseStatusExceptionResolver}
|
* <li>{@link ResponseStatusExceptionResolver}
|
||||||
* for exceptions annotated with @{@link ResponseStatus}.
|
* for exceptions annotated with @{@link ResponseStatus}.
|
||||||
* <li>{@link DefaultHandlerExceptionResolver}
|
* <li>{@link DefaultHandlerExceptionResolver}
|
||||||
* for resolving known Spring exception types
|
* for resolving known Spring exception types
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||||
ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver = new ExceptionHandlerExceptionResolver();
|
ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver = new ExceptionHandlerExceptionResolver();
|
||||||
exceptionHandlerExceptionResolver.setApplicationContext(this.applicationContext);
|
|
||||||
exceptionHandlerExceptionResolver.setContentNegotiationManager(mvcContentNegotiationManager());
|
exceptionHandlerExceptionResolver.setContentNegotiationManager(mvcContentNegotiationManager());
|
||||||
exceptionHandlerExceptionResolver.setMessageConverters(getMessageConverters());
|
exceptionHandlerExceptionResolver.setMessageConverters(getMessageConverters());
|
||||||
|
exceptionHandlerExceptionResolver.setApplicationContext(this.applicationContext);
|
||||||
exceptionHandlerExceptionResolver.afterPropertiesSet();
|
exceptionHandlerExceptionResolver.afterPropertiesSet();
|
||||||
|
|
||||||
exceptionResolvers.add(exceptionHandlerExceptionResolver);
|
exceptionResolvers.add(exceptionHandlerExceptionResolver);
|
||||||
exceptionResolvers.add(new ResponseStatusExceptionResolver());
|
|
||||||
|
ResponseStatusExceptionResolver responseStatusExceptionResolver = new ResponseStatusExceptionResolver();
|
||||||
|
responseStatusExceptionResolver.setMessageSource(this.applicationContext);
|
||||||
|
exceptionResolvers.add(responseStatusExceptionResolver);
|
||||||
|
|
||||||
exceptionResolvers.add(new DefaultHandlerExceptionResolver());
|
exceptionResolvers.add(new DefaultHandlerExceptionResolver());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,28 +17,35 @@
|
|||||||
package org.springframework.web.servlet.config.annotation;
|
package org.springframework.web.servlet.config.annotation;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.context.annotation.ScopedProxyMode;
|
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.core.convert.ConversionService;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.format.annotation.DateTimeFormat.ISO;
|
import org.springframework.format.annotation.DateTimeFormat.ISO;
|
||||||
import org.springframework.format.support.FormattingConversionService;
|
import org.springframework.format.support.FormattingConversionService;
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||||
|
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||||
import org.springframework.mock.web.test.MockServletContext;
|
import org.springframework.mock.web.test.MockServletContext;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.validation.Validator;
|
import org.springframework.validation.Validator;
|
||||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
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.bind.support.ConfigurableWebBindingInitializer;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
@@ -63,6 +70,7 @@ import static org.junit.Assert.*;
|
|||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Sebastien Deleuze
|
||||||
*/
|
*/
|
||||||
public class WebMvcConfigurationSupportTests {
|
public class WebMvcConfigurationSupportTests {
|
||||||
|
|
||||||
@@ -169,10 +177,9 @@ public class WebMvcConfigurationSupportTests {
|
|||||||
@Test
|
@Test
|
||||||
public void handlerExceptionResolver() throws Exception {
|
public void handlerExceptionResolver() throws Exception {
|
||||||
HandlerExceptionResolverComposite compositeResolver =
|
HandlerExceptionResolverComposite compositeResolver =
|
||||||
this.wac.getBean("handlerExceptionResolver", HandlerExceptionResolverComposite.class);
|
this.wac.getBean("handlerExceptionResolver", HandlerExceptionResolverComposite.class);
|
||||||
|
|
||||||
assertEquals(0, compositeResolver.getOrder());
|
assertEquals(0, compositeResolver.getOrder());
|
||||||
|
|
||||||
List<HandlerExceptionResolver> expectedResolvers = compositeResolver.getExceptionResolvers();
|
List<HandlerExceptionResolver> expectedResolvers = compositeResolver.getExceptionResolvers();
|
||||||
|
|
||||||
assertEquals(ExceptionHandlerExceptionResolver.class, expectedResolvers.get(0).getClass());
|
assertEquals(ExceptionHandlerExceptionResolver.class, expectedResolvers.get(0).getClass());
|
||||||
@@ -181,6 +188,18 @@ public class WebMvcConfigurationSupportTests {
|
|||||||
|
|
||||||
ExceptionHandlerExceptionResolver eher = (ExceptionHandlerExceptionResolver) expectedResolvers.get(0);
|
ExceptionHandlerExceptionResolver eher = (ExceptionHandlerExceptionResolver) expectedResolvers.get(0);
|
||||||
assertNotNull(eher.getApplicationContext());
|
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() {
|
public TestController testController() {
|
||||||
return new 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 {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user