Browse Source

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
pull/906/head
Rossen Stoyanchev 9 years ago
parent
commit
f84a0c914a
  1. 16
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
  2. 6
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java
  3. 4
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java
  4. 11
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java
  5. 4
      spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml

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

@ -1,5 +1,5 @@ @@ -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.
@ -364,7 +364,11 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { @@ -364,7 +364,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);
@ -372,10 +376,10 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { @@ -372,10 +376,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;
}

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

@ -192,9 +192,9 @@ public class ViewResolversBeanDefinitionParser implements BeanDefinitionParser { @@ -192,9 +192,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;
}

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

@ -119,6 +119,10 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport @@ -119,6 +119,10 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
this.contentNegotiationManager = contentNegotiationManager;
}
public ContentNegotiationManager getContentNegotiationManager() {
return this.contentNegotiationManager;
}
/**
* Indicate whether a {@link HttpServletResponse#SC_NOT_ACCEPTABLE 406 Not Acceptable}
* status code should be returned if no suitable view can be found.

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

@ -691,7 +691,7 @@ public class MvcNamespaceTests { @@ -691,7 +691,7 @@ public class MvcNamespaceTests {
@Test
public void testContentNegotiationManager() throws Exception {
loadBeanDefinitions("mvc-config-content-negotiation-manager.xml", 14);
loadBeanDefinitions("mvc-config-content-negotiation-manager.xml", 15);
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
ContentNegotiationManager manager = mapping.getContentNegotiationManager();
@ -699,6 +699,15 @@ public class MvcNamespaceTests { @@ -699,6 +699,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

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

@ -9,6 +9,10 @@ @@ -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>

Loading…
Cancel
Save