diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java index 20dc615dbc6..76b70affe14 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java @@ -30,6 +30,7 @@ import org.springframework.boot.actuate.properties.ManagementServerProperties; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration; import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration; +import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; @@ -69,6 +70,7 @@ public class EndpointWebMvcAutoConfigurationTests { this.applicationContext.register(RootConfig.class, PropertyPlaceholderAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class); @@ -86,6 +88,7 @@ public class EndpointWebMvcAutoConfigurationTests { this.applicationContext.register(RootConfig.class, DifferentPortConfig.class, PropertyPlaceholderAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class); @@ -103,6 +106,7 @@ public class EndpointWebMvcAutoConfigurationTests { this.applicationContext.register(RootConfig.class, DisableConfig.class, PropertyPlaceholderAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class); @@ -124,6 +128,7 @@ public class EndpointWebMvcAutoConfigurationTests { ManagementServerPropertiesAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class); this.applicationContext.refresh(); @@ -143,6 +148,7 @@ public class EndpointWebMvcAutoConfigurationTests { ManagementServerPropertiesAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class); this.applicationContext.refresh(); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfigurationTests.java index c84a1263528..efc159fc4ca 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfigurationTests.java @@ -23,6 +23,7 @@ import org.jolokia.http.AgentServlet; import org.junit.After; import org.junit.Test; import org.springframework.boot.TestUtils; +import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor; @@ -59,7 +60,7 @@ public class JolokiaAutoConfigurationTests { public void agentServletRegisteredWithAppContext() throws Exception { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); this.context.register(Config.class, WebMvcAutoConfiguration.class, - JolokiaAutoConfiguration.class); + HttpMessageConvertersAutoConfiguration.class, JolokiaAutoConfiguration.class); this.context.refresh(); assertEquals(1, this.context.getBeanNamesForType(AgentServlet.class).length); } @@ -69,7 +70,7 @@ public class JolokiaAutoConfigurationTests { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); TestUtils.addEnviroment(this.context, "endpoints.jolokia.enabled:false"); this.context.register(Config.class, WebMvcAutoConfiguration.class, - JolokiaAutoConfiguration.class); + HttpMessageConvertersAutoConfiguration.class, JolokiaAutoConfiguration.class); this.context.refresh(); assertEquals(0, this.context.getBeanNamesForType(AgentServlet.class).length); } @@ -78,7 +79,7 @@ public class JolokiaAutoConfigurationTests { public void agentServletRegisteredWithServletContainer() throws Exception { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); this.context.register(Config.class, WebMvcAutoConfiguration.class, - JolokiaAutoConfiguration.class); + HttpMessageConvertersAutoConfiguration.class, JolokiaAutoConfiguration.class); this.context.refresh(); Servlet servlet = null; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfigurationTests.java index 0f659f68263..dec634cac72 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementSecurityAutoConfigurationTests.java @@ -22,6 +22,7 @@ import org.springframework.boot.TestUtils; import org.springframework.boot.autoconfigure.AutoConfigurationReportLoggingInitializer; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.context.initializer.LoggingApplicationContextInitializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -66,6 +67,7 @@ public class ManagementSecurityAutoConfigurationTests { this.context.setServletContext(new MockServletContext()); this.context.register(SecurityAutoConfiguration.class, ManagementSecurityAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); @@ -82,6 +84,7 @@ public class ManagementSecurityAutoConfigurationTests { this.context.setServletContext(new MockServletContext()); this.context.register(EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class, SecurityAutoConfiguration.class, ManagementSecurityAutoConfiguration.class, @@ -125,6 +128,7 @@ public class ManagementSecurityAutoConfigurationTests { this.context.setServletContext(new MockServletContext()); this.context.register(SecurityAutoConfiguration.class, ManagementSecurityAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersAutoConfiguration.java new file mode 100644 index 00000000000..a470db057e3 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersAutoConfiguration.java @@ -0,0 +1,97 @@ +/* + * Copyright 2012-2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.web; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * @author Dave Syer + */ +@Configuration +@ConditionalOnClass(HttpMessageConverter.class) +public class HttpMessageConvertersAutoConfiguration { + + @Autowired(required = false) + private List> converters = Collections.emptyList(); + + @Bean + @ConditionalOnMissingBean + public HttpMessageConverters messageConverters() { + List> converters = new ArrayList>( + this.converters); + return new HttpMessageConverters(converters); + } + + @Configuration + @ConditionalOnBean(ObjectMapper.class) + @ConditionalOnClass(ObjectMapper.class) + protected static class ObjectMappers { + + @Autowired + private ListableBeanFactory beanFactory; + + @PostConstruct + public void init() { + Collection mappers = BeanFactoryUtils + .beansOfTypeIncludingAncestors(this.beanFactory, ObjectMapper.class) + .values(); + Collection modules = BeanFactoryUtils.beansOfTypeIncludingAncestors( + this.beanFactory, Module.class).values(); + for (ObjectMapper mapper : mappers) { + mapper.registerModules(modules); + } + } + + @Bean + @ConditionalOnMissingBean + @Primary + public ObjectMapper jacksonObjectMapper() { + return new ObjectMapper(); + } + + @Bean + @ConditionalOnMissingBean + public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter( + ObjectMapper objectMapper) { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + converter.setObjectMapper(objectMapper); + return converter; + } + + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java index cba287676a5..4f0b052d9d8 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java @@ -17,19 +17,16 @@ package org.springframework.boot.autoconfigure.web; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; -import javax.annotation.PostConstruct; import javax.servlet.Servlet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -41,7 +38,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.convert.converter.Converter; @@ -52,7 +48,6 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.format.Formatter; import org.springframework.format.FormatterRegistry; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.context.request.RequestContextListener; import org.springframework.web.filter.HiddenHttpMethodFilter; @@ -69,9 +64,6 @@ import org.springframework.web.servlet.view.BeanNameViewResolver; import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.ObjectMapper; - /** * {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}. * @@ -111,17 +103,6 @@ public class WebMvcAutoConfiguration { } } - @Autowired(required = false) - private List> converters = Collections.emptyList(); - - @Bean - @ConditionalOnMissingBean - public HttpMessageConverters messageConverters() { - List> converters = new ArrayList>( - this.converters); - return new HttpMessageConverters(converters); - } - @Bean @ConditionalOnMissingBean(HiddenHttpMethodFilter.class) public HiddenHttpMethodFilter hiddenHttpMethodFilter() { @@ -155,45 +136,6 @@ public class WebMvcAutoConfiguration { converters.addAll(this.messageConverters.getMessageConverters()); } - @Configuration - @ConditionalOnBean(ObjectMapper.class) - @ConditionalOnClass(ObjectMapper.class) - protected static class ObjectMappers { - - @Autowired - private ListableBeanFactory beanFactory; - - @PostConstruct - public void init() { - Collection mappers = BeanFactoryUtils - .beansOfTypeIncludingAncestors(this.beanFactory, - ObjectMapper.class).values(); - Collection modules = BeanFactoryUtils - .beansOfTypeIncludingAncestors(this.beanFactory, Module.class) - .values(); - for (ObjectMapper mapper : mappers) { - mapper.registerModules(modules); - } - } - - @Bean - @ConditionalOnMissingBean - @Primary - public ObjectMapper jacksonObjectMapper() { - return new ObjectMapper(); - } - - @Bean - @ConditionalOnMissingBean - public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter( - ObjectMapper objectMapper) { - MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); - converter.setObjectMapper(objectMapper); - return converter; - } - - } - @Bean @ConditionalOnMissingBean(InternalResourceViewResolver.class) public InternalResourceViewResolver defaultViewResolver() { diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index ed699f8673c..474efadd653 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -21,6 +21,7 @@ org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfigura org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\ org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\ +org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationReportLoggingInitializerTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationReportLoggingInitializerTests.java index de6063e6caa..7eb6a69c184 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationReportLoggingInitializerTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationReportLoggingInitializerTests.java @@ -29,6 +29,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -180,7 +181,7 @@ public class AutoConfigurationReportLoggingInitializerTests { } @Configuration - @Import(WebMvcAutoConfiguration.class) + @Import({ WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) static class Config { } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/DeviceResolverAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/DeviceResolverAutoConfigurationTests.java index 25e46bb9d19..138dd78999b 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/DeviceResolverAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/DeviceResolverAutoConfigurationTests.java @@ -16,14 +16,12 @@ package org.springframework.boot.autoconfigure.mobile; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - import java.lang.reflect.Field; import java.util.List; import org.junit.After; import org.junit.Test; +import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor; @@ -37,6 +35,9 @@ import org.springframework.util.ReflectionUtils; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + /** * Tests for {@link DeviceResolverAutoConfiguration}. * @@ -76,6 +77,7 @@ public class DeviceResolverAutoConfigurationTests { public void deviceResolverHandlerInterceptorRegistered() throws Exception { AnnotationConfigEmbeddedWebApplicationContext context = new AnnotationConfigEmbeddedWebApplicationContext(); context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, DeviceResolverAutoConfiguration.class); context.refresh(); RequestMappingHandlerMapping mapping = (RequestMappingHandlerMapping) context diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersAutoConfigurationTests.java new file mode 100644 index 00000000000..4ee137dbcd2 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersAutoConfigurationTests.java @@ -0,0 +1,181 @@ +/* + * Copyright 2012-2013 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.web; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import static org.hamcrest.Matchers.hasItem; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.verify; + +/** + * @author Dave Syer + */ +public class HttpMessageConvertersAutoConfigurationTests { + + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void customJacksonConverter() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(JacksonConfig.class, + HttpMessageConvertersAutoConfiguration.class); + this.context.refresh(); + MappingJackson2HttpMessageConverter converter = this.context + .getBean(MappingJackson2HttpMessageConverter.class); + assertEquals(this.context.getBean(ObjectMapper.class), + converter.getObjectMapper()); + HttpMessageConverters converters = this.context + .getBean(HttpMessageConverters.class); + assertTrue(converters.getMessageConverters().contains(converter)); + } + + @Test + public void customJacksonModules() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(ModulesConfig.class, + HttpMessageConvertersAutoConfiguration.class); + this.context.refresh(); + ObjectMapper mapper = this.context.getBean(ObjectMapper.class); + + @SuppressWarnings({ "unchecked", "unused" }) + ObjectMapper result = verify(mapper).registerModules( + (Iterable) argThat(hasItem(this.context.getBean(Module.class)))); + } + + @Test + public void doubleModuleRegistration() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(DoubleModulesConfig.class, + HttpMessageConvertersAutoConfiguration.class); + this.context.refresh(); + ObjectMapper mapper = this.context.getBean(ObjectMapper.class); + assertEquals("{\"foo\":\"bar\"}", mapper.writeValueAsString(new Foo())); + } + + @Configuration + protected static class JacksonConfig { + + @Bean + public MappingJackson2HttpMessageConverter jacksonMessaegConverter() { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + converter.setObjectMapper(objectMapper()); + return converter; + } + + @Bean + public ObjectMapper objectMapper() { + return new ObjectMapper(); + } + + } + + @Configuration + protected static class ModulesConfig { + + @Bean + public Module jacksonModule() { + return new SimpleModule(); + } + + @Bean + @Primary + public ObjectMapper objectMapper() { + return Mockito.mock(ObjectMapper.class); + } + + } + + @Configuration + protected static class DoubleModulesConfig { + + @Bean + public Module jacksonModule() { + SimpleModule module = new SimpleModule(); + module.addSerializer(Foo.class, new JsonSerializer() { + + @Override + public void serialize(Foo value, JsonGenerator jgen, + SerializerProvider provider) throws IOException, + JsonProcessingException { + jgen.writeStartObject(); + jgen.writeStringField("foo", "bar"); + jgen.writeEndObject(); + } + }); + return module; + } + + @Bean + @Primary + public ObjectMapper objectMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(jacksonModule()); + return mapper; + } + + } + + protected static class Foo { + + private String name; + + private Foo() { + + } + + static Foo create() { + return new Foo(); + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java index 4ea3868e6de..f3b33a073a9 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java @@ -16,7 +16,6 @@ package org.springframework.boot.autoconfigure.web; -import java.io.IOException; import java.lang.reflect.Field; import java.util.LinkedHashMap; import java.util.List; @@ -29,17 +28,14 @@ import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.mockito.Mockito; import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.MockEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.util.ReflectionUtils; import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.HandlerMapping; @@ -51,22 +47,10 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.servlet.view.AbstractView; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.module.SimpleModule; - import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItem; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.verify; /** * Tests for {@link WebMvcAutoConfiguration}. @@ -93,25 +77,32 @@ public class WebMvcAutoConfigurationTests { @Test public void handerAdaptersCreated() throws Exception { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); - this.context.register(Config.class, WebMvcAutoConfiguration.class); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class); this.context.refresh(); assertEquals(3, this.context.getBeanNamesForType(HandlerAdapter.class).length); + assertFalse(this.context.getBean(RequestMappingHandlerAdapter.class) + .getMessageConverters().isEmpty()); + assertEquals(this.context.getBean(HttpMessageConverters.class) + .getMessageConverters(), + this.context.getBean(RequestMappingHandlerAdapter.class) + .getMessageConverters()); } @Test public void handerMappingsCreated() throws Exception { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); - this.context.register(Config.class, WebMvcAutoConfiguration.class); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class); this.context.refresh(); assertEquals(6, this.context.getBeanNamesForType(HandlerMapping.class).length); - assertFalse(this.context.getBean(RequestMappingHandlerAdapter.class) - .getMessageConverters().isEmpty()); } @Test public void resourceHandlerMapping() throws Exception { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); - this.context.register(Config.class, WebMvcAutoConfiguration.class); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class); this.context.refresh(); Map> mappingLocations = getMappingLocations(); assertThat(mappingLocations.get("/**").size(), equalTo(5)); @@ -123,7 +114,8 @@ public class WebMvcAutoConfigurationTests { @Test public void resourceHandlerMappingOverrideWebjars() throws Exception { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); - this.context.register(WebJars.class, Config.class, WebMvcAutoConfiguration.class); + this.context.register(WebJars.class, Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class); this.context.refresh(); Map> mappingLocations = getMappingLocations(); assertThat(mappingLocations.get("/webjars/**").size(), equalTo(1)); @@ -135,7 +127,8 @@ public class WebMvcAutoConfigurationTests { public void resourceHandlerMappingOverrideAll() throws Exception { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); this.context.register(AllResources.class, Config.class, - WebMvcAutoConfiguration.class); + WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class); this.context.refresh(); Map> mappingLocations = getMappingLocations(); assertThat(mappingLocations.get("/**").size(), equalTo(1)); @@ -143,46 +136,6 @@ public class WebMvcAutoConfigurationTests { equalTo((Resource) new ClassPathResource("/foo/"))); } - @Test - public void customJacksonConverter() throws Exception { - this.context = new AnnotationConfigEmbeddedWebApplicationContext(); - this.context.register(JacksonConfig.class, Config.class, - WebMvcAutoConfiguration.class); - this.context.refresh(); - MappingJackson2HttpMessageConverter converter = this.context - .getBean(MappingJackson2HttpMessageConverter.class); - assertEquals(this.context.getBean(ObjectMapper.class), - converter.getObjectMapper()); - HttpMessageConverters converters = this.context.getBean(HttpMessageConverters.class); - assertTrue(converters.getMessageConverters().contains(converter)); - assertEquals(converters.getMessageConverters(), - this.context.getBean(RequestMappingHandlerAdapter.class) - .getMessageConverters()); - } - - @Test - public void customJacksonModules() throws Exception { - this.context = new AnnotationConfigEmbeddedWebApplicationContext(); - this.context.register(ModulesConfig.class, Config.class, - WebMvcAutoConfiguration.class); - this.context.refresh(); - ObjectMapper mapper = this.context.getBean(ObjectMapper.class); - - @SuppressWarnings({ "unchecked", "unused" }) - ObjectMapper result = verify(mapper).registerModules( - (Iterable) argThat(hasItem(this.context.getBean(Module.class)))); - } - - @Test - public void doubleModuleRegistration() throws Exception { - this.context = new AnnotationConfigEmbeddedWebApplicationContext(); - this.context.register(DoubleModulesConfig.class, Config.class, - WebMvcAutoConfiguration.class); - this.context.refresh(); - ObjectMapper mapper = this.context.getBean(ObjectMapper.class); - assertEquals("{\"foo\":\"bar\"}", mapper.writeValueAsString(new Foo())); - } - @SuppressWarnings("unchecked") protected Map> getMappingLocations() throws IllegalAccessException { @@ -240,91 +193,6 @@ public class WebMvcAutoConfigurationTests { } - @Configuration - protected static class ModulesConfig { - - @Bean - public Module jacksonModule() { - return new SimpleModule(); - } - - @Bean - @Primary - public ObjectMapper objectMapper() { - return Mockito.mock(ObjectMapper.class); - } - - } - - @Configuration - protected static class DoubleModulesConfig { - - @Bean - public Module jacksonModule() { - SimpleModule module = new SimpleModule(); - module.addSerializer(Foo.class, new JsonSerializer() { - - @Override - public void serialize(Foo value, JsonGenerator jgen, - SerializerProvider provider) throws IOException, - JsonProcessingException { - jgen.writeStartObject(); - jgen.writeStringField("foo", "bar"); - jgen.writeEndObject(); - } - }); - return module; - } - - @Bean - @Primary - public ObjectMapper objectMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(jacksonModule()); - return mapper; - } - - } - - protected static class Foo { - - private String name; - - private Foo() { - - } - - static Foo create() { - return new Foo(); - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - } - - @Configuration - protected static class JacksonConfig { - - @Bean - public MappingJackson2HttpMessageConverter jacksonMessaegConverter() { - MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); - converter.setObjectMapper(objectMapper()); - return converter; - } - - @Bean - public ObjectMapper objectMapper() { - return new ObjectMapper(); - } - - } - @Configuration protected static class Config { diff --git a/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/org/springframework/boot/sample/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java b/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/org/springframework/boot/sample/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java index d6054b521a7..c173c4277cd 100644 --- a/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/org/springframework/boot/sample/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/org/springframework/boot/sample/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java @@ -29,6 +29,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration; import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration; +import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.sample.tomcat.service.HelloWorldService; import org.springframework.boot.sample.tomcat.web.SampleController; @@ -55,7 +56,7 @@ public class NonAutoConfigurationSampleTomcatApplicationTests { @Configuration @Import({ EmbeddedServletContainerAutoConfiguration.class, - DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, + DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) @ComponentScan(basePackageClasses = { SampleController.class, HelloWorldService.class }) public static class NonAutoConfigurationSampleTomcatApplication {