Skip to content

Commit 89c532a

Browse files
lower-casesnicoll
authored andcommitted
Add property to customize Jackson's default leniency
See gh-27659
1 parent ead8305 commit 89c532a

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ public void customize(Jackson2ObjectMapperBuilder builder) {
187187
configurePropertyNamingStrategy(builder);
188188
configureModules(builder);
189189
configureLocale(builder);
190+
configureLeniency(builder);
190191
}
191192

192193
private void configureFeatures(Jackson2ObjectMapperBuilder builder, Map<?, Boolean> features) {
@@ -289,6 +290,11 @@ private void configureLocale(Jackson2ObjectMapperBuilder builder) {
289290
}
290291
}
291292

293+
private void configureLeniency(Jackson2ObjectMapperBuilder builder) {
294+
Boolean lenient = this.jacksonProperties.getLenient();
295+
builder.postConfigurer(objectMapper -> objectMapper.setDefaultLeniency(lenient));
296+
}
297+
292298
private static <T> Collection<T> getBeans(ListableBeanFactory beanFactory, Class<T> type) {
293299
return BeanFactoryUtils.beansOfTypeIncludingAncestors(beanFactory, type).values();
294300
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonProperties.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ public class JacksonProperties {
103103
*/
104104
private Locale locale;
105105

106+
/**
107+
* Setting for leniency, in case of absence it will be considered lenient = true;
108+
*/
109+
private Boolean lenient;
110+
106111
public String getDateFormat() {
107112
return this.dateFormat;
108113
}
@@ -167,4 +172,12 @@ public void setLocale(Locale locale) {
167172
this.locale = locale;
168173
}
169174

175+
public Boolean getLenient() {
176+
return lenient;
177+
}
178+
179+
public void setLenient(Boolean lenient) {
180+
this.lenient = lenient;
181+
}
182+
170183
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import com.fasterxml.jackson.annotation.JsonCreator;
2828
import com.fasterxml.jackson.annotation.JsonCreator.Mode;
29+
import com.fasterxml.jackson.annotation.JsonFormat;
2930
import com.fasterxml.jackson.annotation.JsonInclude;
3031
import com.fasterxml.jackson.core.JsonGenerator;
3132
import com.fasterxml.jackson.core.JsonParser;
@@ -40,6 +41,7 @@
4041
import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
4142
import com.fasterxml.jackson.databind.SerializationFeature;
4243
import com.fasterxml.jackson.databind.SerializerProvider;
44+
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
4345
import com.fasterxml.jackson.databind.module.SimpleModule;
4446
import com.fasterxml.jackson.databind.util.StdDateFormat;
4547
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
@@ -301,6 +303,40 @@ void customTimeZoneFormattingADate() {
301303
});
302304
}
303305

306+
@Test
307+
void disableLeniency() {
308+
this.contextRunner.withPropertyValues("spring.jackson.lenient:false").run((context) -> {
309+
boolean invalidFormat = false;
310+
ObjectMapper mapper = context.getBean(ObjectMapper.class);
311+
try {
312+
mapper.readValue("{\"birthDate\": \"2010-12-30\"}", Person.class);
313+
}
314+
catch (InvalidFormatException e) {
315+
assertThat(e).isNotNull();
316+
invalidFormat = true;
317+
}
318+
assertThat(invalidFormat).isTrue();
319+
});
320+
}
321+
322+
@Test
323+
void enableLeniency() {
324+
this.contextRunner.withPropertyValues("spring.jackson.lenient:true").run((context) -> {
325+
ObjectMapper mapper = context.getBean(ObjectMapper.class);
326+
Person person = mapper.readValue("{\"birthDate\": \"2010-12-30\"}", Person.class);
327+
assertThat(person.getBirthDate()).isNotNull();
328+
});
329+
}
330+
331+
@Test
332+
void defaultLeniency() {
333+
this.contextRunner.run((context) -> {
334+
ObjectMapper mapper = context.getBean(ObjectMapper.class);
335+
Person person = mapper.readValue("{\"birthDate\": \"2010-12-30\"}", Person.class);
336+
assertThat(person.getBirthDate()).isNotNull();
337+
});
338+
}
339+
304340
@Test
305341
void additionalJacksonBuilderCustomization() {
306342
this.contextRunner.withUserConfiguration(ObjectMapperBuilderCustomConfig.class).run((context) -> {
@@ -537,4 +573,19 @@ String getProperty3() {
537573

538574
}
539575

576+
static class Person {
577+
578+
@JsonFormat(pattern = "yyyyMMdd")
579+
private Date birthDate;
580+
581+
public Date getBirthDate() {
582+
return birthDate;
583+
}
584+
585+
public void setBirthDate(Date birthDate) {
586+
this.birthDate = birthDate;
587+
}
588+
589+
}
590+
540591
}

0 commit comments

Comments
 (0)