From f84a0c914a06e79208d5306927ec35a0a3a6e5df Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 29 Oct 2015 18:01:00 -0400 Subject: [PATCH] Detect custom ContentNegotiationViewResolver The element now adds an alias when a ContentNegotiationManager bean is registered with a custom name. This helps to more reliably find such a custom ContentNegotiationManager. Issue: SPR-13559 --- .../AnnotationDrivenBeanDefinitionParser.java | 16 ++++++++++------ .../ViewResolversBeanDefinitionParser.java | 6 +++--- .../view/ContentNegotiatingViewResolver.java | 4 ++++ .../web/servlet/config/MvcNamespaceTests.java | 11 ++++++++++- .../mvc-config-content-negotiation-manager.xml | 4 ++++ 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index ac4873e3fc..8c6081a6f2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -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 { 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 { 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; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java index ff743ba614..8644da5770 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java @@ -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; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java index 1d5a4f8d8c..1fb1fc71ac 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java @@ -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. diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java index 1982cee5e7..8e3c347d79 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java @@ -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 { 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 diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml index 34d609b65c..f213de087a 100644 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml @@ -9,6 +9,10 @@ + + + +