From 1dcf18b16ebbacfdcad9259f808d4949f0668181 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 8 Apr 2015 16:47:49 +0100 Subject: [PATCH] Allow Jackson's serialization inclusion to be configured via the env This commit adds support for configuring an ObjectMapper's serialization inclusion using the environment via the spring.jackson.serialization-inclusion property. The property's value should be one of the values on the JsonInclude.Include enumeration. Relaxed binding of the property value to the enum is supported. For example: spring.jackson.serialization-inclusion: non_null Closes gh-2532 --- .../jackson/JacksonAutoConfiguration.java | 4 ++++ .../jackson/JacksonProperties.java | 18 +++++++++++++-- .../JacksonAutoConfigurationTests.java | 23 +++++++++++++++++++ .../appendix-application-properties.adoc | 1 + 4 files changed, 44 insertions(+), 2 deletions(-) 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 2f83edd77d..f42e493681 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 @@ -176,6 +176,10 @@ public class JacksonAutoConfiguration { if (isJsonPrettyPrint != null && isJsonPrettyPrint) { builder.featuresToEnable(SerializationFeature.INDENT_OUTPUT); } + if (this.jacksonProperties.getSerializationInclusion() != null) { + builder.serializationInclusion(this.jacksonProperties + .getSerializationInclusion()); + } configureFeatures(builder, this.jacksonProperties.getDeserialization()); configureFeatures(builder, this.jacksonProperties.getSerialization()); configureFeatures(builder, this.jacksonProperties.getMapper()); diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java index f90dd107c9..a490a62e41 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java @@ -21,6 +21,7 @@ import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -45,8 +46,7 @@ public class JacksonProperties { /** * Joda date time format string (yyyy-MM-dd HH:mm:ss). If not configured, - * "date-format" will be used as a fallback if it is configured with a format - * string. + * "date-format" will be used as a fallback if it is configured with a format string. */ private String jodaDateTimeFormat; @@ -82,6 +82,12 @@ public class JacksonProperties { */ private Map generator = new HashMap(); + /** + * Controls the inclusion of properties during serialization. Configured with one of + * the values in Jackson's JsonInclude.Include enumeration. + */ + private JsonInclude.Include serializationInclusion; + public String getDateFormat() { return this.dateFormat; } @@ -126,4 +132,12 @@ public class JacksonProperties { return this.generator; } + public JsonInclude.Include getSerializationInclusion() { + return this.serializationInclusion; + } + + public void setSerializationInclusion(JsonInclude.Include serializationInclusion) { + this.serializationInclusion = serializationInclusion; + } + } 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 c99ceba496..481854c9c2 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,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; @@ -387,6 +388,28 @@ public class JacksonAutoConfigurationTests { assertThat(objectMapper.canSerialize(LocalDateTime.class), is(true)); } + @Test + public void defaultSerializationInclusion() { + this.context.register(JacksonAutoConfiguration.class); + this.context.refresh(); + ObjectMapper objectMapper = this.context.getBean( + Jackson2ObjectMapperBuilder.class).build(); + assertThat(objectMapper.getSerializationConfig().getSerializationInclusion(), + is(JsonInclude.Include.ALWAYS)); + } + + @Test + public void customSerializationInclusion() { + this.context.register(JacksonAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.jackson.serialization-inclusion:non_null"); + this.context.refresh(); + ObjectMapper objectMapper = this.context.getBean( + Jackson2ObjectMapperBuilder.class).build(); + assertThat(objectMapper.getSerializationConfig().getSerializationInclusion(), + is(JsonInclude.Include.NON_NULL)); + } + @Configuration protected static class MockObjectMapperConfig { diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 36869e3c08..5714f57996 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -142,6 +142,7 @@ content into your application; rather pick only the properties that you need. spring.jackson.mapper.*= # see Jackson's MapperFeature spring.jackson.parser.*= # see Jackson's JsonParser.Feature spring.jackson.serialization.*= # see Jackson's SerializationFeature + spring.jackson.serialization-inclusion= # Controls the inclusion of properties during serialization (see Jackson's JsonInclude.Include) # THYMELEAF ({sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[ThymeleafAutoConfiguration]) spring.thymeleaf.check-template-location=true