From 49cf30e964f1dc1e80e5e78833e55ac5f5a33f0e Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 29 Sep 2014 17:19:19 -0400 Subject: [PATCH] Update default view resolver in MVC Java config When not ViewResolver's have been registered, detect if the context contains any other ViewResolver beans. If not, add InternalResourceVR to match default DispatcherServlet behavior. Issue: SPR-12267 --- .../WebMvcConfigurationSupport.java | 10 ++ .../WebMvcConfigurationSupportTests.java | 105 ++++++++++++------ 2 files changed, 79 insertions(+), 36 deletions(-) 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 7ee748fcc8..648e64451a 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 @@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletRequest; import javax.xml.transform.Source; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -85,6 +86,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver; import org.springframework.web.servlet.resource.ResourceUrlProvider; import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor; +import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.ViewResolverComposite; import org.springframework.web.util.UrlPathHelper; @@ -798,6 +800,14 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv registry.setApplicationContext(this.applicationContext); configureViewResolvers(registry); + if (registry.getViewResolvers().isEmpty()) { + Map map = BeanFactoryUtils.beansOfTypeIncludingAncestors( + this.applicationContext, ViewResolver.class, true, false); + if (map.isEmpty()) { + registry.getViewResolvers().add(new InternalResourceViewResolver()); + } + } + ViewResolverComposite composite = new ViewResolverComposite(); composite.setOrder(registry.getOrder()); composite.setViewResolvers(registry.getViewResolvers()); 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 114c5138b0..b7d049b6c7 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 @@ -18,12 +18,14 @@ package org.springframework.web.servlet.config.annotation; import java.util.List; import java.util.Locale; +import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.joda.time.DateTime; -import org.junit.Before; import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @@ -44,12 +46,13 @@ 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.support.ConfigurableWebBindingInitializer; -import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.method.support.CompositeUriComponentsContributor; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.HandlerExecutionChain; import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.view.BeanNameViewResolver; +import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.ViewResolverComposite; import org.springframework.web.servlet.handler.AbstractHandlerMapping; import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping; @@ -66,6 +69,7 @@ import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInter import org.springframework.web.util.UrlPathHelper; import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; /** * A test fixture with an {@link WebMvcConfigurationSupport} instance. @@ -76,23 +80,11 @@ import static org.junit.Assert.*; */ public class WebMvcConfigurationSupportTests { - private WebApplicationContext wac; - - - @Before - public void setUp() { - AnnotationConfigWebApplicationContext cxt = new AnnotationConfigWebApplicationContext(); - cxt.setServletContext(new MockServletContext()); - cxt.register(TestConfig.class, ScopedController.class, ScopedProxyController.class); - cxt.refresh(); - - this.wac = cxt; - } - @Test public void requestMappingHandlerMapping() throws Exception { - RequestMappingHandlerMapping handlerMapping = this.wac.getBean(RequestMappingHandlerMapping.class); + ApplicationContext context = initContext(WebConfig.class, ScopedController.class, ScopedProxyController.class); + RequestMappingHandlerMapping handlerMapping = context.getBean(RequestMappingHandlerMapping.class); assertEquals(0, handlerMapping.getOrder()); HandlerExecutionChain chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/")); @@ -109,8 +101,9 @@ public class WebMvcConfigurationSupportTests { @Test public void emptyViewControllerHandlerMapping() { - AbstractHandlerMapping handlerMapping = this.wac.getBean( - "viewControllerHandlerMapping", AbstractHandlerMapping.class); + ApplicationContext context = initContext(WebConfig.class); + String name = "viewControllerHandlerMapping"; + AbstractHandlerMapping handlerMapping = context.getBean(name, AbstractHandlerMapping.class); assertNotNull(handlerMapping); assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder()); @@ -119,7 +112,8 @@ public class WebMvcConfigurationSupportTests { @Test public void beanNameHandlerMapping() throws Exception { - BeanNameUrlHandlerMapping handlerMapping = this.wac.getBean(BeanNameUrlHandlerMapping.class); + ApplicationContext context = initContext(WebConfig.class); + BeanNameUrlHandlerMapping handlerMapping = context.getBean(BeanNameUrlHandlerMapping.class); assertEquals(2, handlerMapping.getOrder()); HttpServletRequest request = new MockHttpServletRequest("GET", "/testController"); @@ -133,8 +127,8 @@ public class WebMvcConfigurationSupportTests { @Test public void emptyResourceHandlerMapping() { - AbstractHandlerMapping handlerMapping = this.wac.getBean( - "resourceHandlerMapping", AbstractHandlerMapping.class); + ApplicationContext context = initContext(WebConfig.class); + AbstractHandlerMapping handlerMapping = context.getBean("resourceHandlerMapping", AbstractHandlerMapping.class); assertNotNull(handlerMapping); assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder()); @@ -143,8 +137,9 @@ public class WebMvcConfigurationSupportTests { @Test public void emptyDefaultServletHandlerMapping() { - AbstractHandlerMapping handlerMapping = this.wac.getBean( - "defaultServletHandlerMapping", AbstractHandlerMapping.class); + ApplicationContext context = initContext(WebConfig.class); + String name = "defaultServletHandlerMapping"; + AbstractHandlerMapping handlerMapping = context.getBean(name, AbstractHandlerMapping.class); assertNotNull(handlerMapping); assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder()); @@ -153,7 +148,8 @@ public class WebMvcConfigurationSupportTests { @Test public void requestMappingHandlerAdapter() throws Exception { - RequestMappingHandlerAdapter adapter = this.wac.getBean(RequestMappingHandlerAdapter.class); + ApplicationContext context = initContext(WebConfig.class); + RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class); assertEquals(9, adapter.getMessageConverters().size()); ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer(); @@ -175,7 +171,8 @@ public class WebMvcConfigurationSupportTests { @Test public void uriComponentsContributor() throws Exception { - CompositeUriComponentsContributor uriComponentsContributor = this.wac.getBean( + ApplicationContext context = initContext(WebConfig.class); + CompositeUriComponentsContributor uriComponentsContributor = context.getBean( MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME, CompositeUriComponentsContributor.class); @@ -184,8 +181,9 @@ public class WebMvcConfigurationSupportTests { @Test public void handlerExceptionResolver() throws Exception { + ApplicationContext context = initContext(WebConfig.class); HandlerExceptionResolverComposite compositeResolver = - this.wac.getBean("handlerExceptionResolver", HandlerExceptionResolverComposite.class); + context.getBean("handlerExceptionResolver", HandlerExceptionResolverComposite.class); assertEquals(0, compositeResolver.getOrder()); @@ -203,20 +201,37 @@ public class WebMvcConfigurationSupportTests { assertEquals(1, interceptors.size()); assertEquals(JsonViewResponseBodyAdvice.class, interceptors.get(0).getClass()); } - + @Test - public void emptyViewResolver() throws Exception { - ViewResolverComposite compositeResolver = this.wac.getBean(ViewResolverComposite.class); - assertEquals(Ordered.LOWEST_PRECEDENCE, compositeResolver.getOrder()); - List resolvers = compositeResolver.getViewResolvers(); - assertEquals(0, resolvers.size()); - assertNull(compositeResolver.resolveViewName("anyViewName", Locale.ENGLISH)); + public void mvcViewResolver() { + ApplicationContext context = initContext(WebConfig.class); + ViewResolverComposite resolver = context.getBean("mvcViewResolver", ViewResolverComposite.class); + + Map map = BeanFactoryUtils.beansOfTypeIncludingAncestors( + context, ViewResolver.class, true, false); + + assertNotNull(resolver); + assertEquals(1, resolver.getViewResolvers().size()); + assertEquals(InternalResourceViewResolver.class, resolver.getViewResolvers().get(0).getClass()); + assertEquals(Ordered.LOWEST_PRECEDENCE, resolver.getOrder()); + } + + @Test + public void mvcViewResolverWithExistingResolver() throws Exception { + ApplicationContext context = initContext(WebConfig.class, ViewResolverConfig.class); + ViewResolverComposite resolver = context.getBean("mvcViewResolver", ViewResolverComposite.class); + + assertNotNull(resolver); + assertEquals(0, resolver.getViewResolvers().size()); + assertEquals(Ordered.LOWEST_PRECEDENCE, resolver.getOrder()); + assertNull(resolver.resolveViewName("anyViewName", Locale.ENGLISH)); } @Test public void defaultPathMatchConfiguration() throws Exception { - UrlPathHelper urlPathHelper = this.wac.getBean(UrlPathHelper.class); - PathMatcher pathMatcher = this.wac.getBean(PathMatcher.class); + ApplicationContext context = initContext(WebConfig.class); + UrlPathHelper urlPathHelper = context.getBean(UrlPathHelper.class); + PathMatcher pathMatcher = context.getBean(PathMatcher.class); assertNotNull(urlPathHelper); assertNotNull(pathMatcher); @@ -224,9 +239,18 @@ public class WebMvcConfigurationSupportTests { } + private ApplicationContext initContext(Class... configClasses) { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.setServletContext(new MockServletContext()); + context.register(configClasses); + context.refresh(); + return context; + } + + @EnableWebMvc @Configuration - public static class TestConfig { + public static class WebConfig { @Bean(name="/testController") public TestController testController() { @@ -234,6 +258,15 @@ public class WebMvcConfigurationSupportTests { } } + @Configuration + public static class ViewResolverConfig { + + @Bean + public ViewResolver beanNameViewResolver() { + return new BeanNameViewResolver(); + } + } + @Controller public static class TestController {