From 5039441b11f91abf95f894fd1f671186b03420e4 Mon Sep 17 00:00:00 2001 From: Lovekesh Garg Date: Sat, 14 Aug 2021 23:12:15 +0530 Subject: [PATCH] Added property to customize Jackson default leniency --- .../jackson/JacksonAutoConfiguration.java | 6 +++ .../jackson/JacksonProperties.java | 13 +++++ .../JacksonAutoConfigurationTests.java | 51 +++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java index 915eb534c9f8..d43bb686ffc7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java @@ -187,6 +187,7 @@ public void customize(Jackson2ObjectMapperBuilder builder) { configurePropertyNamingStrategy(builder); configureModules(builder); configureLocale(builder); + configureLeniency(builder); } private void configureFeatures(Jackson2ObjectMapperBuilder builder, Map features) { @@ -289,6 +290,11 @@ private void configureLocale(Jackson2ObjectMapperBuilder builder) { } } + private void configureLeniency(Jackson2ObjectMapperBuilder builder) { + Boolean lenient = this.jacksonProperties.getLenient(); + builder.postConfigurer(objectMapper -> objectMapper.setDefaultLeniency(lenient)); + } + private static Collection getBeans(ListableBeanFactory beanFactory, Class type) { return BeanFactoryUtils.beansOfTypeIncludingAncestors(beanFactory, type).values(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java index f11baa6f4857..46c4d2ced5fd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java @@ -103,6 +103,11 @@ public class JacksonProperties { */ private Locale locale; + /** + * Setting for leniency, in case of absence it will be considered lenient = true; + */ + private Boolean lenient; + public String getDateFormat() { return this.dateFormat; } @@ -167,4 +172,12 @@ public void setLocale(Locale locale) { this.locale = locale; } + public Boolean getLenient() { + return lenient; + } + + public void setLenient(Boolean lenient) { + this.lenient = lenient; + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java index 6c770b029887..10ddd64271c4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java @@ -26,6 +26,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator.Mode; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; @@ -40,6 +41,7 @@ import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.util.StdDateFormat; import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; @@ -301,6 +303,40 @@ void customTimeZoneFormattingADate() { }); } + @Test + void disableLeniency() { + this.contextRunner.withPropertyValues("spring.jackson.lenient:false").run((context) -> { + boolean invalidFormat = false; + ObjectMapper mapper = context.getBean(ObjectMapper.class); + try { + mapper.readValue("{\"birthDate\": \"2010-12-30\"}", Person.class); + } + catch (InvalidFormatException e) { + assertThat(e).isNotNull(); + invalidFormat = true; + } + assertThat(invalidFormat).isTrue(); + }); + } + + @Test + void enableLeniency() { + this.contextRunner.withPropertyValues("spring.jackson.lenient:true").run((context) -> { + ObjectMapper mapper = context.getBean(ObjectMapper.class); + Person person = mapper.readValue("{\"birthDate\": \"2010-12-30\"}", Person.class); + assertThat(person.getBirthDate()).isNotNull(); + }); + } + + @Test + void defaultLeniency() { + this.contextRunner.run((context) -> { + ObjectMapper mapper = context.getBean(ObjectMapper.class); + Person person = mapper.readValue("{\"birthDate\": \"2010-12-30\"}", Person.class); + assertThat(person.getBirthDate()).isNotNull(); + }); + } + @Test void additionalJacksonBuilderCustomization() { this.contextRunner.withUserConfiguration(ObjectMapperBuilderCustomConfig.class).run((context) -> { @@ -537,4 +573,19 @@ String getProperty3() { } + static class Person { + + @JsonFormat(pattern = "yyyyMMdd") + private Date birthDate; + + public Date getBirthDate() { + return birthDate; + } + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + } + }