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 9ccd6cb8d73..704d3da3971 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 @@ -158,6 +158,8 @@ public final class JacksonAutoConfiguration { @Override public void customize(JsonMapper.Builder builder) { super.customize(builder); + configureFeatures(builder, properties().getRead(), builder::configure); + configureFeatures(builder, properties().getWrite(), builder::configure); configureFeatures(builder, properties().getJson().getRead(), builder::configure); configureFeatures(builder, properties().getJson().getWrite(), 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 1b2a77adef3..f62083ad76b 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 @@ -25,6 +25,8 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.PropertyAccessor; import org.jspecify.annotations.Nullable; +import tools.jackson.core.StreamReadFeature; +import tools.jackson.core.StreamWriteFeature; import tools.jackson.core.json.JsonReadFeature; import tools.jackson.core.json.JsonWriteFeature; import tools.jackson.databind.DeserializationFeature; @@ -123,6 +125,16 @@ public class JacksonProperties { private final Datatype datatype = new Datatype(); + /** + * Jackson on/off token reader features common to multiple formats. + */ + private final Map read = new EnumMap<>(StreamReadFeature.class); + + /** + * Jackson on/off token writer features common to multiple formats. + */ + private final Map write = new EnumMap<>(StreamWriteFeature.class); + private final Json json = new Json(); public @Nullable String getDateFormat() { @@ -217,6 +229,14 @@ public class JacksonProperties { return this.datatype; } + public Map getRead() { + return this.read; + } + + public Map getWrite() { + return this.write; + } + public Json getJson() { return this.json; } 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 f4228667ccc..915dc4c4212 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 @@ -347,6 +347,24 @@ class JacksonAutoConfigurationTests { }); } + @Test + void enableWriteBigDecimalAsPlain() { + this.contextRunner.withPropertyValues("spring.jackson.write.write-bigdecimal-as-plain:true").run((context) -> { + JsonMapper mapper = context.getBean(JsonMapper.class); + assertThat(StreamWriteFeature.WRITE_BIGDECIMAL_AS_PLAIN.enabledByDefault()).isFalse(); + assertThat(mapper.isEnabled(StreamWriteFeature.WRITE_BIGDECIMAL_AS_PLAIN)).isTrue(); + }); + } + + @Test + void enableStringDuplicateDetection() { + this.contextRunner.withPropertyValues("spring.jackson.read.strict-duplicate-detection:true").run((context) -> { + JsonMapper mapper = context.getBean(JsonMapper.class); + assertThat(StreamReadFeature.STRICT_DUPLICATE_DETECTION.enabledByDefault()).isFalse(); + assertThat(mapper.isEnabled(StreamReadFeature.STRICT_DUPLICATE_DETECTION)).isTrue(); + }); + } + @EnumSource @ParameterizedTest void enableDatetimeFeature(MapperType mapperType) {