Skip to content

Commit 49cf30e

Browse files
committed
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
1 parent ae43b17 commit 49cf30e

File tree

2 files changed

+79
-36
lines changed

2 files changed

+79
-36
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import javax.xml.transform.Source;
2727

2828
import org.springframework.beans.BeanUtils;
29+
import org.springframework.beans.factory.BeanFactoryUtils;
2930
import org.springframework.beans.factory.BeanInitializationException;
3031
import org.springframework.context.ApplicationContext;
3132
import org.springframework.context.ApplicationContextAware;
@@ -85,6 +86,7 @@
8586
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
8687
import org.springframework.web.servlet.resource.ResourceUrlProvider;
8788
import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor;
89+
import org.springframework.web.servlet.view.InternalResourceViewResolver;
8890
import org.springframework.web.servlet.view.ViewResolverComposite;
8991
import org.springframework.web.util.UrlPathHelper;
9092

@@ -798,6 +800,14 @@ public ViewResolver mvcViewResolver() {
798800
registry.setApplicationContext(this.applicationContext);
799801
configureViewResolvers(registry);
800802

803+
if (registry.getViewResolvers().isEmpty()) {
804+
Map<String, ViewResolver> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(
805+
this.applicationContext, ViewResolver.class, true, false);
806+
if (map.isEmpty()) {
807+
registry.getViewResolvers().add(new InternalResourceViewResolver());
808+
}
809+
}
810+
801811
ViewResolverComposite composite = new ViewResolverComposite();
802812
composite.setOrder(registry.getOrder());
803813
composite.setViewResolvers(registry.getViewResolvers());

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

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818

1919
import java.util.List;
2020
import java.util.Locale;
21+
import java.util.Map;
2122
import javax.servlet.http.HttpServletRequest;
2223

2324
import org.joda.time.DateTime;
24-
import org.junit.Before;
2525
import org.junit.Test;
2626
import org.springframework.beans.DirectFieldAccessor;
27+
import org.springframework.beans.factory.BeanFactoryUtils;
28+
import org.springframework.context.ApplicationContext;
2729
import org.springframework.context.annotation.Bean;
2830
import org.springframework.context.annotation.Configuration;
2931
import org.springframework.context.annotation.Scope;
@@ -44,12 +46,13 @@
4446
import org.springframework.web.bind.annotation.PathVariable;
4547
import org.springframework.web.bind.annotation.RequestMapping;
4648
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
47-
import org.springframework.web.context.WebApplicationContext;
4849
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
4950
import org.springframework.web.method.support.CompositeUriComponentsContributor;
5051
import org.springframework.web.servlet.HandlerExceptionResolver;
5152
import org.springframework.web.servlet.HandlerExecutionChain;
5253
import org.springframework.web.servlet.ViewResolver;
54+
import org.springframework.web.servlet.view.BeanNameViewResolver;
55+
import org.springframework.web.servlet.view.InternalResourceViewResolver;
5356
import org.springframework.web.servlet.view.ViewResolverComposite;
5457
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
5558
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
@@ -66,6 +69,7 @@
6669
import org.springframework.web.util.UrlPathHelper;
6770

6871
import static org.junit.Assert.*;
72+
import static org.junit.Assert.assertEquals;
6973

7074
/**
7175
* A test fixture with an {@link WebMvcConfigurationSupport} instance.
@@ -76,23 +80,11 @@
7680
*/
7781
public class WebMvcConfigurationSupportTests {
7882

79-
private WebApplicationContext wac;
80-
81-
82-
@Before
83-
public void setUp() {
84-
AnnotationConfigWebApplicationContext cxt = new AnnotationConfigWebApplicationContext();
85-
cxt.setServletContext(new MockServletContext());
86-
cxt.register(TestConfig.class, ScopedController.class, ScopedProxyController.class);
87-
cxt.refresh();
88-
89-
this.wac = cxt;
90-
}
91-
9283

9384
@Test
9485
public void requestMappingHandlerMapping() throws Exception {
95-
RequestMappingHandlerMapping handlerMapping = this.wac.getBean(RequestMappingHandlerMapping.class);
86+
ApplicationContext context = initContext(WebConfig.class, ScopedController.class, ScopedProxyController.class);
87+
RequestMappingHandlerMapping handlerMapping = context.getBean(RequestMappingHandlerMapping.class);
9688
assertEquals(0, handlerMapping.getOrder());
9789

9890
HandlerExecutionChain chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/"));
@@ -109,8 +101,9 @@ public void requestMappingHandlerMapping() throws Exception {
109101

110102
@Test
111103
public void emptyViewControllerHandlerMapping() {
112-
AbstractHandlerMapping handlerMapping = this.wac.getBean(
113-
"viewControllerHandlerMapping", AbstractHandlerMapping.class);
104+
ApplicationContext context = initContext(WebConfig.class);
105+
String name = "viewControllerHandlerMapping";
106+
AbstractHandlerMapping handlerMapping = context.getBean(name, AbstractHandlerMapping.class);
114107

115108
assertNotNull(handlerMapping);
116109
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder());
@@ -119,7 +112,8 @@ public void emptyViewControllerHandlerMapping() {
119112

120113
@Test
121114
public void beanNameHandlerMapping() throws Exception {
122-
BeanNameUrlHandlerMapping handlerMapping = this.wac.getBean(BeanNameUrlHandlerMapping.class);
115+
ApplicationContext context = initContext(WebConfig.class);
116+
BeanNameUrlHandlerMapping handlerMapping = context.getBean(BeanNameUrlHandlerMapping.class);
123117
assertEquals(2, handlerMapping.getOrder());
124118

125119
HttpServletRequest request = new MockHttpServletRequest("GET", "/testController");
@@ -133,8 +127,8 @@ public void beanNameHandlerMapping() throws Exception {
133127

134128
@Test
135129
public void emptyResourceHandlerMapping() {
136-
AbstractHandlerMapping handlerMapping = this.wac.getBean(
137-
"resourceHandlerMapping", AbstractHandlerMapping.class);
130+
ApplicationContext context = initContext(WebConfig.class);
131+
AbstractHandlerMapping handlerMapping = context.getBean("resourceHandlerMapping", AbstractHandlerMapping.class);
138132

139133
assertNotNull(handlerMapping);
140134
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder());
@@ -143,8 +137,9 @@ public void emptyResourceHandlerMapping() {
143137

144138
@Test
145139
public void emptyDefaultServletHandlerMapping() {
146-
AbstractHandlerMapping handlerMapping = this.wac.getBean(
147-
"defaultServletHandlerMapping", AbstractHandlerMapping.class);
140+
ApplicationContext context = initContext(WebConfig.class);
141+
String name = "defaultServletHandlerMapping";
142+
AbstractHandlerMapping handlerMapping = context.getBean(name, AbstractHandlerMapping.class);
148143

149144
assertNotNull(handlerMapping);
150145
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder());
@@ -153,7 +148,8 @@ public void emptyDefaultServletHandlerMapping() {
153148

154149
@Test
155150
public void requestMappingHandlerAdapter() throws Exception {
156-
RequestMappingHandlerAdapter adapter = this.wac.getBean(RequestMappingHandlerAdapter.class);
151+
ApplicationContext context = initContext(WebConfig.class);
152+
RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class);
157153
assertEquals(9, adapter.getMessageConverters().size());
158154

159155
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer();
@@ -175,7 +171,8 @@ public void requestMappingHandlerAdapter() throws Exception {
175171

176172
@Test
177173
public void uriComponentsContributor() throws Exception {
178-
CompositeUriComponentsContributor uriComponentsContributor = this.wac.getBean(
174+
ApplicationContext context = initContext(WebConfig.class);
175+
CompositeUriComponentsContributor uriComponentsContributor = context.getBean(
179176
MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME,
180177
CompositeUriComponentsContributor.class);
181178

@@ -184,8 +181,9 @@ public void uriComponentsContributor() throws Exception {
184181

185182
@Test
186183
public void handlerExceptionResolver() throws Exception {
184+
ApplicationContext context = initContext(WebConfig.class);
187185
HandlerExceptionResolverComposite compositeResolver =
188-
this.wac.getBean("handlerExceptionResolver", HandlerExceptionResolverComposite.class);
186+
context.getBean("handlerExceptionResolver", HandlerExceptionResolverComposite.class);
189187

190188
assertEquals(0, compositeResolver.getOrder());
191189

@@ -203,37 +201,72 @@ public void handlerExceptionResolver() throws Exception {
203201
assertEquals(1, interceptors.size());
204202
assertEquals(JsonViewResponseBodyAdvice.class, interceptors.get(0).getClass());
205203
}
206-
204+
207205
@Test
208-
public void emptyViewResolver() throws Exception {
209-
ViewResolverComposite compositeResolver = this.wac.getBean(ViewResolverComposite.class);
210-
assertEquals(Ordered.LOWEST_PRECEDENCE, compositeResolver.getOrder());
211-
List<ViewResolver> resolvers = compositeResolver.getViewResolvers();
212-
assertEquals(0, resolvers.size());
213-
assertNull(compositeResolver.resolveViewName("anyViewName", Locale.ENGLISH));
206+
public void mvcViewResolver() {
207+
ApplicationContext context = initContext(WebConfig.class);
208+
ViewResolverComposite resolver = context.getBean("mvcViewResolver", ViewResolverComposite.class);
209+
210+
Map<String, ViewResolver> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(
211+
context, ViewResolver.class, true, false);
212+
213+
assertNotNull(resolver);
214+
assertEquals(1, resolver.getViewResolvers().size());
215+
assertEquals(InternalResourceViewResolver.class, resolver.getViewResolvers().get(0).getClass());
216+
assertEquals(Ordered.LOWEST_PRECEDENCE, resolver.getOrder());
217+
}
218+
219+
@Test
220+
public void mvcViewResolverWithExistingResolver() throws Exception {
221+
ApplicationContext context = initContext(WebConfig.class, ViewResolverConfig.class);
222+
ViewResolverComposite resolver = context.getBean("mvcViewResolver", ViewResolverComposite.class);
223+
224+
assertNotNull(resolver);
225+
assertEquals(0, resolver.getViewResolvers().size());
226+
assertEquals(Ordered.LOWEST_PRECEDENCE, resolver.getOrder());
227+
assertNull(resolver.resolveViewName("anyViewName", Locale.ENGLISH));
214228
}
215229

216230
@Test
217231
public void defaultPathMatchConfiguration() throws Exception {
218-
UrlPathHelper urlPathHelper = this.wac.getBean(UrlPathHelper.class);
219-
PathMatcher pathMatcher = this.wac.getBean(PathMatcher.class);
232+
ApplicationContext context = initContext(WebConfig.class);
233+
UrlPathHelper urlPathHelper = context.getBean(UrlPathHelper.class);
234+
PathMatcher pathMatcher = context.getBean(PathMatcher.class);
220235

221236
assertNotNull(urlPathHelper);
222237
assertNotNull(pathMatcher);
223238
assertEquals(AntPathMatcher.class, pathMatcher.getClass());
224239
}
225240

226241

242+
private ApplicationContext initContext(Class... configClasses) {
243+
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
244+
context.setServletContext(new MockServletContext());
245+
context.register(configClasses);
246+
context.refresh();
247+
return context;
248+
}
249+
250+
227251
@EnableWebMvc
228252
@Configuration
229-
public static class TestConfig {
253+
public static class WebConfig {
230254

231255
@Bean(name="/testController")
232256
public TestController testController() {
233257
return new TestController();
234258
}
235259
}
236260

261+
@Configuration
262+
public static class ViewResolverConfig {
263+
264+
@Bean
265+
public ViewResolver beanNameViewResolver() {
266+
return new BeanNameViewResolver();
267+
}
268+
}
269+
237270

238271
@Controller
239272
public static class TestController {

0 commit comments

Comments
 (0)