diff --git a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java index 657c77c838c..ead5b96baf5 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java @@ -63,6 +63,8 @@ public class ContentNegotiationManagerFactoryBean private MediaType defaultContentType; + private ContentNegotiationStrategy defaultNegotiationStrategy; + private ContentNegotiationManager contentNegotiationManager; private ServletContext servletContext; @@ -187,6 +189,17 @@ public class ContentNegotiationManagerFactoryBean this.defaultContentType = defaultContentType; } + /** + * Set the {@link ContentNegotiationStrategy} to be used to resolving the default content type. + *
This content type will be used when neither the request path extension, + * nor a request parameter, nor the {@code Accept} header could help determine + * the requested content type. + * @since 4.1.2 + */ + public void setDefaultContentType(ContentNegotiationStrategy defaultStrategy) { + this.defaultNegotiationStrategy = defaultStrategy; + } + @Override public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; @@ -226,6 +239,10 @@ public class ContentNegotiationManagerFactoryBean strategies.add(new FixedContentNegotiationStrategy(this.defaultContentType)); } + if(this.defaultNegotiationStrategy != null) { + strategies.add(defaultNegotiationStrategy); + } + this.contentNegotiationManager = new ContentNegotiationManager(strategies); } diff --git a/spring-web/src/test/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBeanTests.java b/spring-web/src/test/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBeanTests.java index 195724a65ef..fc186a8d50a 100644 --- a/spring-web/src/test/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBeanTests.java +++ b/spring-web/src/test/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBeanTests.java @@ -168,4 +168,17 @@ public class ContentNegotiationManagerFactoryBeanTests { assertEquals(Arrays.asList(MediaType.APPLICATION_JSON), manager.resolveMediaTypes(this.webRequest)); } + // SPR-12286 + @Test + public void setDefaultContentTypeWithStrategy() throws Exception { + this.factoryBean.setDefaultContentType(new FixedContentNegotiationStrategy(MediaType.APPLICATION_JSON)); + this.factoryBean.afterPropertiesSet(); + ContentNegotiationManager manager = this.factoryBean.getObject(); + + assertEquals(Arrays.asList(MediaType.APPLICATION_JSON), manager.resolveMediaTypes(this.webRequest)); + + this.servletRequest.addHeader("Accept", MediaType.ALL_VALUE); + assertEquals(Arrays.asList(MediaType.APPLICATION_JSON), manager.resolveMediaTypes(this.webRequest)); + } + } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java index f093dde696a..5499741c042 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java @@ -22,6 +22,7 @@ import javax.servlet.ServletContext; import org.springframework.http.MediaType; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.accept.ContentNegotiationManagerFactoryBean; +import org.springframework.web.accept.ContentNegotiationStrategy; /** * Helps with configuring a {@link ContentNegotiationManager}. @@ -167,6 +168,18 @@ public class ContentNegotiationConfigurer { return this; } + /** + * Set the {@link ContentNegotiationStrategy} to be used to resolving the default content type. + *
This content type will be used when neither the request path extension, + * nor a request parameter, nor the {@code Accept} header could help determine + * the requested content type. + * @since 4.1.2 + */ + public ContentNegotiationConfigurer defaultContentType(ContentNegotiationStrategy defaultStrategy) { + this.factoryBean.setDefaultContentType(defaultStrategy); + return this; + } + /** * Return the configured {@link ContentNegotiationManager} instance */ diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurerTests.java index d504f3a2fed..665ae146da7 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -24,6 +24,7 @@ import org.junit.Test; import org.springframework.http.MediaType; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.web.accept.ContentNegotiationManager; +import org.springframework.web.accept.FixedContentNegotiationStrategy; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.ServletWebRequest; @@ -110,4 +111,12 @@ public class ContentNegotiationConfigurerTests { assertEquals(Arrays.asList(MediaType.APPLICATION_JSON), manager.resolveMediaTypes(this.webRequest)); } + + @Test + public void setDefaultContentTypeWithStrategy() throws Exception { + this.configurer.defaultContentType(new FixedContentNegotiationStrategy(MediaType.APPLICATION_JSON)); + ContentNegotiationManager manager = this.configurer.getContentNegotiationManager(); + + assertEquals(Arrays.asList(MediaType.APPLICATION_JSON), manager.resolveMediaTypes(this.webRequest)); + } }