diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc index 5cc0247607e..83af2db9331 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc @@ -74,31 +74,31 @@ These features are described in several enums (in Jackson) that map onto propert | `spring.jackson.datatype.json-node.` | `true`, `false` +| javadoc:com.fasterxml.jackson.annotation.JsonInclude$Include[] +| configprop:spring.jackson.default-property-inclusion[] +| `always`, `non_null`, `non_absent`, `non_default`, `non_empty` +|=== + | javadoc:tools.jackson.databind.DeserializationFeature[] | `spring.jackson.deserialization.` | `true`, `false` -| javadoc:tools.jackson.databind.MapperFeature[] -| `spring.jackson.mapper.` -| `true`, `false` - | javadoc:tools.jackson.core.JsonReadFeature[] -| `spring.jackson.read.` +| `spring.jackson.json.read.` | `true`, `false` | javadoc:tools.jackson.core.JsonWriteFeature[] -| `spring.jackson.write.` +| `spring.jackson.json.write.` +| `true`, `false` + +| javadoc:tools.jackson.databind.MapperFeature[] +| `spring.jackson.mapper.` | `true`, `false` | javadoc:tools.jackson.databind.SerializationFeature[] | `spring.jackson.serialization.` | `true`, `false` -| javadoc:com.fasterxml.jackson.annotation.JsonInclude$Include[] -| configprop:spring.jackson.default-property-inclusion[] -| `always`, `non_null`, `non_absent`, `non_default`, `non_empty` -|=== - For example, to enable pretty print, set `spring.jackson.serialization.indent_output=true`. Note that, thanks to the use of xref:reference:features/external-config.adoc#features.external-config.typesafe-configuration-properties.relaxed-binding[relaxed binding], the case of `indent_output` does not have to match the case of the corresponding enum constant, which is `INDENT_OUTPUT`. diff --git a/module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java b/module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java index 9598174f35f..d3f0fa0c440 100644 --- a/module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java +++ b/module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java @@ -175,8 +175,8 @@ public final class JacksonAutoConfiguration { configureFeatures(builder, this.jacksonProperties.getDeserialization(), builder::configure); configureFeatures(builder, this.jacksonProperties.getSerialization(), builder::configure); configureFeatures(builder, this.jacksonProperties.getMapper(), builder::configure); - configureFeatures(builder, this.jacksonProperties.getRead(), builder::configure); - configureFeatures(builder, this.jacksonProperties.getWrite(), builder::configure); + configureFeatures(builder, this.jacksonProperties.getJson().getRead(), builder::configure); + configureFeatures(builder, this.jacksonProperties.getJson().getWrite(), builder::configure); configureFeatures(builder, this.jacksonProperties.getDatatype().getDatetime(), builder::configure); configureFeatures(builder, this.jacksonProperties.getDatatype().getEnum(), builder::configure); configureFeatures(builder, this.jacksonProperties.getDatatype().getJsonNode(), builder::configure); diff --git a/module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonProperties.java b/module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonProperties.java index e101ead7e88..13cde58244d 100644 --- a/module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonProperties.java +++ b/module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonProperties.java @@ -81,16 +81,6 @@ public class JacksonProperties { */ private final Map mapper = new EnumMap<>(MapperFeature.class); - /** - * Jackson on/off features for readers. - */ - private final Map read = new EnumMap<>(JsonReadFeature.class); - - /** - * Jackson on/off features for writers. - */ - private final Map write = new EnumMap<>(JsonWriteFeature.class); - /** * Controls the inclusion of properties during serialization. Configured with one of * the values in Jackson's JsonInclude.Include enumeration. @@ -121,6 +111,8 @@ public class JacksonProperties { private final Datatype datatype = new Datatype(); + private final Json json = new Json(); + public @Nullable String getDateFormat() { return this.dateFormat; } @@ -153,14 +145,6 @@ public class JacksonProperties { return this.mapper; } - public Map getRead() { - return this.read; - } - - public Map getWrite() { - return this.write; - } - public JsonInclude.@Nullable Include getDefaultPropertyInclusion() { return this.defaultPropertyInclusion; } @@ -205,6 +189,10 @@ public class JacksonProperties { return this.datatype; } + public Json getJson() { + return this.json; + } + public enum ConstructorDetectorStrategy { /** @@ -261,4 +249,26 @@ public class JacksonProperties { } + public static class Json { + + /** + * Jackson on/off token reader features that are specific to JSON. + */ + private final Map read = new EnumMap<>(JsonReadFeature.class); + + /** + * Jackson on/off token writer features that are specific to JSON. + */ + private final Map write = new EnumMap<>(JsonWriteFeature.class); + + public Map getRead() { + return this.read; + } + + public Map getWrite() { + return this.write; + } + + } + } diff --git a/module/spring-boot-jackson/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/module/spring-boot-jackson/src/main/resources/META-INF/additional-spring-configuration-metadata.json index aa702701555..b647101d34d 100644 --- a/module/spring-boot-jackson/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/module/spring-boot-jackson/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -15,6 +15,26 @@ "deprecation": { "level": "error" } + }, + { + "name": "spring.jackson.read", + "type": "java.util.Map", + "description": "Jackson on/off token reader features that are specific to JSON.", + "sourceType": "org.springframework.boot.jackson.autoconfigure.JacksonProperties", + "deprecation": { + "level": "error", + "replacement": "spring.jackson.json.read" + } + }, + { + "name": "spring.jackson.write", + "type": "java.util.Map", + "description": "Jackson on/off token writer features that are specific to JSON.", + "sourceType": "org.springframework.boot.jackson.autoconfigure.JacksonProperties", + "deprecation": { + "level": "error", + "replacement": "spring.jackson.json.write" + } } ] } diff --git a/module/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java b/module/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java index e4a97b7b6f7..29da3354ee9 100644 --- a/module/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java +++ b/module/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java @@ -237,8 +237,8 @@ class JacksonAutoConfigurationTests { } @Test - void enableReadFeature() { - this.contextRunner.withPropertyValues("spring.jackson.read.allow_single_quotes:true").run((context) -> { + void enableJsonReadFeature() { + this.contextRunner.withPropertyValues("spring.jackson.json.read.allow_single_quotes:true").run((context) -> { JsonMapper mapper = context.getBean(JsonMapper.class); assertThat(JsonReadFeature.ALLOW_SINGLE_QUOTES.enabledByDefault()).isFalse(); assertThat(mapper.isEnabled(JsonReadFeature.ALLOW_SINGLE_QUOTES)).isTrue(); @@ -246,18 +246,19 @@ class JacksonAutoConfigurationTests { } @Test - void enableWriteFeature() { - this.contextRunner.withPropertyValues("spring.jackson.write.write_numbers_as_strings:true").run((context) -> { - JsonMapper mapper = context.getBean(JsonMapper.class); - JsonWriteFeature feature = JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS; - assertThat(feature.enabledByDefault()).isFalse(); - assertThat(mapper.isEnabled(feature)).isTrue(); - }); + void enableJsonWriteFeature() { + this.contextRunner.withPropertyValues("spring.jackson.json.write.write_numbers_as_strings:true") + .run((context) -> { + JsonMapper mapper = context.getBean(JsonMapper.class); + JsonWriteFeature feature = JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS; + assertThat(feature.enabledByDefault()).isFalse(); + assertThat(mapper.isEnabled(feature)).isTrue(); + }); } @Test void disableWriteFeature() { - this.contextRunner.withPropertyValues("spring.jackson.write.write_hex_upper_case:false").run((context) -> { + this.contextRunner.withPropertyValues("spring.jackson.json.write.write_hex_upper_case:false").run((context) -> { JsonMapper mapper = context.getBean(JsonMapper.class); assertThat(JsonWriteFeature.WRITE_HEX_UPPER_CASE.enabledByDefault()).isTrue(); assertThat(mapper.isEnabled(JsonWriteFeature.WRITE_HEX_UPPER_CASE)).isFalse();