Skip to content

Commit 563a120

Browse files
committed
Detect custom ContentNegotiationViewResolver
The <mvc:annotation-driven> element now adds an alias when a ContentNegotiationManager bean is registered with a custom name. This helps <mvc:view-resolvers> to more reliably find such a custom ContentNegotiationManager. Issue: SPR-13559
1 parent 78fc5bb commit 563a120

File tree

5 files changed

+31
-10
lines changed

5 files changed

+31
-10
lines changed

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -352,18 +352,22 @@ else if (javaxValidationPresent) {
352352
private RuntimeBeanReference getContentNegotiationManager(Element element, Object source, ParserContext parserContext) {
353353
RuntimeBeanReference contentNegotiationManagerRef;
354354
if (element.hasAttribute("content-negotiation-manager")) {
355-
contentNegotiationManagerRef = new RuntimeBeanReference(element.getAttribute("content-negotiation-manager"));
355+
String name = element.getAttribute("content-negotiation-manager");
356+
contentNegotiationManagerRef = new RuntimeBeanReference(name);
357+
if (!CONTENT_NEGOTIATION_MANAGER_BEAN_NAME.equals(name)) {
358+
parserContext.getRegistry().registerAlias(name, CONTENT_NEGOTIATION_MANAGER_BEAN_NAME);
359+
}
356360
}
357361
else {
358362
RootBeanDefinition factoryBeanDef = new RootBeanDefinition(ContentNegotiationManagerFactoryBean.class);
359363
factoryBeanDef.setSource(source);
360364
factoryBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
361365
factoryBeanDef.getPropertyValues().add("mediaTypes", getDefaultMediaTypes());
362366

363-
String beanName = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
364-
parserContext.getReaderContext().getRegistry().registerBeanDefinition(beanName , factoryBeanDef);
365-
parserContext.registerComponent(new BeanComponentDefinition(factoryBeanDef, beanName));
366-
contentNegotiationManagerRef = new RuntimeBeanReference(beanName);
367+
String name = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
368+
parserContext.getReaderContext().getRegistry().registerBeanDefinition(name , factoryBeanDef);
369+
parserContext.registerComponent(new BeanComponentDefinition(factoryBeanDef, name));
370+
contentNegotiationManagerRef = new RuntimeBeanReference(name);
367371
}
368372
return contentNegotiationManagerRef;
369373
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,9 @@ private BeanDefinition createContentNegotiatingViewResolver(Element resolverElem
185185
if (resolverElement.hasAttribute("use-not-acceptable")) {
186186
values.add("useNotAcceptableStatusCode", resolverElement.getAttribute("use-not-acceptable"));
187187
}
188-
String beanName = AnnotationDrivenBeanDefinitionParser.CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
189-
if (context.getRegistry().containsBeanDefinition(beanName)) {
190-
values.add("contentNegotiationManager", new RuntimeBeanReference(beanName));
188+
String name = AnnotationDrivenBeanDefinitionParser.CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
189+
if (context.getRegistry().containsBeanDefinition(name) || context.getRegistry().isAlias(name)) {
190+
values.add("contentNegotiationManager", new RuntimeBeanReference(name));
191191
}
192192
return beanDef;
193193
}

spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ public void setContentNegotiationManager(ContentNegotiationManager contentNegoti
124124
this.contentNegotiationManager = contentNegotiationManager;
125125
}
126126

127+
public ContentNegotiationManager getContentNegotiationManager() {
128+
return this.contentNegotiationManager;
129+
}
130+
127131
/**
128132
* Indicate whether the extension of the request path should be used to determine the requested media type,
129133
* in favor of looking at the {@code Accept} header. The default value is {@code true}.

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,14 +680,23 @@ public void testViewControllersDefaultConfig() {
680680

681681
@Test
682682
public void testContentNegotiationManager() throws Exception {
683-
loadBeanDefinitions("mvc-config-content-negotiation-manager.xml", 13);
683+
loadBeanDefinitions("mvc-config-content-negotiation-manager.xml", 15);
684684

685685
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
686686
ContentNegotiationManager manager = mapping.getContentNegotiationManager();
687687

688688
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo.xml");
689689
NativeWebRequest webRequest = new ServletWebRequest(request);
690690
assertEquals(Arrays.asList(MediaType.valueOf("application/rss+xml")), manager.resolveMediaTypes(webRequest));
691+
692+
ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class);
693+
assertNotNull(compositeResolver);
694+
assertEquals("Actual: " + compositeResolver.getViewResolvers(), 1, compositeResolver.getViewResolvers().size());
695+
696+
ViewResolver resolver = compositeResolver.getViewResolvers().get(0);
697+
assertEquals(ContentNegotiatingViewResolver.class, resolver.getClass());
698+
ContentNegotiatingViewResolver cnvr = (ContentNegotiatingViewResolver) resolver;
699+
assertSame(manager, cnvr.getContentNegotiationManager());
691700
}
692701

693702
@Test

spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
1111

12+
<mvc:view-resolvers>
13+
<mvc:content-negotiation/>
14+
</mvc:view-resolvers>
15+
1216
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
1317
<property name="mediaTypes">
1418
<value>

0 commit comments

Comments
 (0)