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
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -352,7 +352,11 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
private RuntimeBeanReference getContentNegotiationManager(Element element, Object source, ParserContext parserContext) {
|
||||
RuntimeBeanReference contentNegotiationManagerRef;
|
||||
if (element.hasAttribute("content-negotiation-manager")) {
|
||||
contentNegotiationManagerRef = new RuntimeBeanReference(element.getAttribute("content-negotiation-manager"));
|
||||
String name = element.getAttribute("content-negotiation-manager");
|
||||
contentNegotiationManagerRef = new RuntimeBeanReference(name);
|
||||
if (!CONTENT_NEGOTIATION_MANAGER_BEAN_NAME.equals(name)) {
|
||||
parserContext.getRegistry().registerAlias(name, CONTENT_NEGOTIATION_MANAGER_BEAN_NAME);
|
||||
}
|
||||
}
|
||||
else {
|
||||
RootBeanDefinition factoryBeanDef = new RootBeanDefinition(ContentNegotiationManagerFactoryBean.class);
|
||||
@@ -360,10 +364,10 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
factoryBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
factoryBeanDef.getPropertyValues().add("mediaTypes", getDefaultMediaTypes());
|
||||
|
||||
String beanName = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
|
||||
parserContext.getReaderContext().getRegistry().registerBeanDefinition(beanName , factoryBeanDef);
|
||||
parserContext.registerComponent(new BeanComponentDefinition(factoryBeanDef, beanName));
|
||||
contentNegotiationManagerRef = new RuntimeBeanReference(beanName);
|
||||
String name = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
|
||||
parserContext.getReaderContext().getRegistry().registerBeanDefinition(name , factoryBeanDef);
|
||||
parserContext.registerComponent(new BeanComponentDefinition(factoryBeanDef, name));
|
||||
contentNegotiationManagerRef = new RuntimeBeanReference(name);
|
||||
}
|
||||
return contentNegotiationManagerRef;
|
||||
}
|
||||
|
||||
@@ -185,9 +185,9 @@ public class ViewResolversBeanDefinitionParser implements BeanDefinitionParser {
|
||||
if (resolverElement.hasAttribute("use-not-acceptable")) {
|
||||
values.add("useNotAcceptableStatusCode", resolverElement.getAttribute("use-not-acceptable"));
|
||||
}
|
||||
String beanName = AnnotationDrivenBeanDefinitionParser.CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
|
||||
if (context.getRegistry().containsBeanDefinition(beanName)) {
|
||||
values.add("contentNegotiationManager", new RuntimeBeanReference(beanName));
|
||||
String name = AnnotationDrivenBeanDefinitionParser.CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
|
||||
if (context.getRegistry().containsBeanDefinition(name) || context.getRegistry().isAlias(name)) {
|
||||
values.add("contentNegotiationManager", new RuntimeBeanReference(name));
|
||||
}
|
||||
return beanDef;
|
||||
}
|
||||
|
||||
@@ -124,6 +124,10 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
this.contentNegotiationManager = contentNegotiationManager;
|
||||
}
|
||||
|
||||
public ContentNegotiationManager getContentNegotiationManager() {
|
||||
return this.contentNegotiationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether the extension of the request path should be used to determine the requested media type,
|
||||
* in favor of looking at the {@code Accept} header. The default value is {@code true}.
|
||||
|
||||
@@ -680,7 +680,7 @@ public class MvcNamespaceTests {
|
||||
|
||||
@Test
|
||||
public void testContentNegotiationManager() throws Exception {
|
||||
loadBeanDefinitions("mvc-config-content-negotiation-manager.xml", 13);
|
||||
loadBeanDefinitions("mvc-config-content-negotiation-manager.xml", 15);
|
||||
|
||||
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
|
||||
ContentNegotiationManager manager = mapping.getContentNegotiationManager();
|
||||
@@ -688,6 +688,15 @@ public class MvcNamespaceTests {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo.xml");
|
||||
NativeWebRequest webRequest = new ServletWebRequest(request);
|
||||
assertEquals(Arrays.asList(MediaType.valueOf("application/rss+xml")), manager.resolveMediaTypes(webRequest));
|
||||
|
||||
ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class);
|
||||
assertNotNull(compositeResolver);
|
||||
assertEquals("Actual: " + compositeResolver.getViewResolvers(), 1, compositeResolver.getViewResolvers().size());
|
||||
|
||||
ViewResolver resolver = compositeResolver.getViewResolvers().get(0);
|
||||
assertEquals(ContentNegotiatingViewResolver.class, resolver.getClass());
|
||||
ContentNegotiatingViewResolver cnvr = (ContentNegotiatingViewResolver) resolver;
|
||||
assertSame(manager, cnvr.getContentNegotiationManager());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
|
||||
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
|
||||
|
||||
<mvc:view-resolvers>
|
||||
<mvc:content-negotiation/>
|
||||
</mvc:view-resolvers>
|
||||
|
||||
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
|
||||
<property name="mediaTypes">
|
||||
<value>
|
||||
|
||||
Reference in New Issue
Block a user