Browse Source

Set ResponseStatusExceptionResolver.messageSource in the MVC Java config

Issue: SPR-12380
(cherry picked from commit 17b9bde)
pull/690/head
Juergen Hoeller 11 years ago
parent
commit
aa82da8507
  1. 84
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java
  2. 35
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java

84
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
* *
* <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());
} }

35
spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java

@ -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 {
}
} }

Loading…
Cancel
Save