diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java index 86fdc55a2a..bf3c9eb241 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java @@ -16,12 +16,17 @@ package org.springframework.boot.autoconfigure.hateoas; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.LinkDiscoverers; @@ -29,27 +34,63 @@ import org.springframework.hateoas.Resource; import org.springframework.hateoas.config.EnableEntityLinks; import org.springframework.hateoas.config.EnableHypermediaSupport; import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.plugin.core.Plugin; import org.springframework.web.bind.annotation.RequestMapping; +import com.fasterxml.jackson.databind.ObjectMapper; + /** * {@link EnableAutoConfiguration Auto-configuration} for Spring HATEOAS's * {@link EnableHypermediaSupport}. * * @author Roy Clarkson * @author Oliver Gierke + * @author Andy Wilkinson * @since 1.1.0 */ @Configuration @ConditionalOnClass({ Resource.class, RequestMapping.class, Plugin.class }) @ConditionalOnWebApplication -@AutoConfigureAfter(WebMvcAutoConfiguration.class) +@AutoConfigureAfter({ WebMvcAutoConfiguration.class, JacksonAutoConfiguration.class }) public class HypermediaAutoConfiguration { @Configuration @ConditionalOnMissingBean(LinkDiscoverers.class) @EnableHypermediaSupport(type = HypermediaType.HAL) protected static class HypermediaConfiguration { + + @ConditionalOnClass({ Jackson2ObjectMapperBuilder.class, ObjectMapper.class }) + protected static class HalObjectMapperConfiguration { + + @Autowired(required = false) + private Jackson2ObjectMapperBuilder objectMapperBuilder; + + @Bean + public BeanPostProcessor halObjectMapperConfigurer() { + return new BeanPostProcessor() { + + @Override + public Object postProcessAfterInitialization(Object bean, + String beanName) throws BeansException { + if (HalObjectMapperConfiguration.this.objectMapperBuilder != null + && bean instanceof ObjectMapper + && "_halObjectMapper".equals(beanName)) { + HalObjectMapperConfiguration.this.objectMapperBuilder + .configure((ObjectMapper) bean); + } + return bean; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, + String beanName) throws BeansException { + return bean; + } + + }; + } + } } @Configuration diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java index 27e4f93202..961449fcc2 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java @@ -18,6 +18,8 @@ package org.springframework.boot.autoconfigure.hateoas; import org.junit.After; import org.junit.Test; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.context.annotation.Configuration; import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.LinkDiscoverer; @@ -28,6 +30,9 @@ import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType import org.springframework.hateoas.hal.HalLinkDiscoverer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -78,6 +83,20 @@ public class HypermediaAutoConfigurationTests { this.context.getBean(LinkDiscoverers.class); } + @Test + public void jacksonConfigurationIsAppliedToTheHalObjectMapper() { + this.context = new AnnotationConfigWebApplicationContext(); + this.context.register(HypermediaAutoConfiguration.class, + JacksonAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.jackson.serialization.INDENT_OUTPUT:true"); + this.context.refresh(); + ObjectMapper objectMapper = this.context.getBean("_halObjectMapper", + ObjectMapper.class); + assertTrue(objectMapper.getSerializationConfig().isEnabled( + SerializationFeature.INDENT_OUTPUT)); + } + @Configuration @EnableHypermediaSupport(type = HypermediaType.HAL) static class SampleConfig {