From 7f2be6ce270a038da43bf6c1d902e23787f13109 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 21 Sep 2015 16:48:50 +0100 Subject: [PATCH] Add auto-configuration for Jackson's parameter names module The parameter names module allows users of Java 8 that have compiled their code with the -parameters option to avoid the name for annotations to map the json onto constructor and method parameters with the names of the parameters being used instead. This commit adds auto-configuration for the module that will only be enabled when running on Java 8. Closes gh-3804 --- spring-boot-autoconfigure/pom.xml | 4 +++ .../jackson/JacksonAutoConfiguration.java | 17 +++++++++ .../JacksonAutoConfigurationTests.java | 36 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index fe499d443f..5f8a7e34bb 100644 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -55,6 +55,10 @@ jackson-datatype-jsr310 true + + com.fasterxml.jackson.module + jackson-module-parameter-names + com.google.code.gson gson diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java index 46d02886c2..d0f646074b 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java @@ -33,6 +33,8 @@ 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.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnJava; +import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.JavaVersion; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; @@ -44,12 +46,14 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaDateFormat; import com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; /** * Auto configuration for Jackson. The following auto-configuration will get applied: @@ -129,6 +133,19 @@ public class JacksonAutoConfiguration { } + @Configuration + @ConditionalOnJava(JavaVersion.EIGHT) + @ConditionalOnClass(ParameterNamesModule.class) + static class ParameterNamesModuleConfiguration { + + @Bean + @ConditionalOnMissingBean(ParameterNamesModule.class) + public ParameterNamesModule parametersNameModule() { + return new ParameterNamesModule(JsonCreator.Mode.PROPERTIES); + } + + } + @Configuration @ConditionalOnClass({ ObjectMapper.class, Jackson2ObjectMapperBuilder.class }) @EnableConfigurationProperties(JacksonProperties.class) diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java index ed1aeb1631..d85aec2619 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java @@ -37,6 +37,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonCreator.Mode; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; @@ -50,8 +52,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.util.StdDateFormat; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItem; @@ -412,6 +416,28 @@ public class JacksonAutoConfigurationTests { objectMapper.writeValueAsString(dateTime)); } + @Test + public void parameterNamesModuleIsAutoConfigured() { + assertParameterNamesModuleCreatorBinding(Mode.PROPERTIES, + JacksonAutoConfiguration.class); + } + + @Test + public void customParameterNamesModuleCanBeConfigured() { + assertParameterNamesModuleCreatorBinding(Mode.DELEGATING, + ParameterNamesModuleConfig.class, JacksonAutoConfiguration.class); + } + + private void assertParameterNamesModuleCreatorBinding(Mode expectedMode, + Class... configClasses) { + this.context.register(configClasses); + this.context.refresh(); + Annotated annotated = mock(Annotated.class); + Mode mode = this.context.getBean(ObjectMapper.class).getDeserializationConfig() + .getAnnotationIntrospector().findCreatorBinding(annotated); + assertThat(mode, is(equalTo(expectedMode))); + } + public static class MyDateFormat extends SimpleDateFormat { public MyDateFormat() { @@ -469,6 +495,16 @@ public class JacksonAutoConfigurationTests { } + @Configuration + protected static class ParameterNamesModuleConfig { + + @Bean + public ParameterNamesModule parameterNamesModule() { + return new ParameterNamesModule(JsonCreator.Mode.DELEGATING); + } + + } + protected static final class Foo { private String name;