Spring Boot defaults allow both dates and datetime values in LocalDate
.
E.g. for following DTO:
public class Person {
private LocalDate birthDate;
//getter & setters
}
Both of the following are acceptable:
{
"birthDate" : "2021-07-24"
}
{
"birthDate" : "2021-07-24T17:00:00Z"
}
Jackson has a lenient
flag that can be set to reject dates with time:
@JsonFormat(pattern="uuuu-MM-dd", lenient = OptBoolean.FALSE)
private LocalDate birthDate;
Is there a corresponding Spring Boot application properties flag that can be set to apply globally to all LocalDate
fields, so that the annotation does not need to be added to every LocalDate
field and without needing to define a custom deserializer like this?
Overview. When using JSON format, Spring Boot will use an ObjectMapper instance to serialize responses and deserialize requests. In this tutorial, we'll take a look at the most common ways to configure the serialization and deserialization options. To learn more about Jackson, be sure to check out our Jackson tutorial.
ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model ( JsonNode ), as well as related functionality for performing conversions.
Assuming no configuration is required, just a plain ObjectMapper will do. It's OK to be declared as static. But in environment like Spring, IMHO you should declare it as a bean.
Auto-configuration for Jackson is provided and Jackson is part of spring-boot-starter-json . When Jackson is on the classpath an ObjectMapper bean is automatically configured. Several configuration properties are provided for customizing the configuration of the ObjectMapper .
Before addressing the question of setting the lenient
flag globally, it's worth noting that setting this flag in this particular example (which was written in a version of Jackson prior to 2.13.0) is not what actually achieved the desired result. Rather, it is the presence of the pattern
annotation element that caused the value to be rejected, not the lenient
annotation element. The following would therefore be sufficient to reject the example datetime value:
@JsonFormat(pattern="uuuu-MM-dd")
private LocalDate birthDate;
Regarding the question of setting the lenient
flag globally in a Spring Boot application, the answer to this question depends on the version of Spring Boot and Jackson being used, as newer versions of these libraries have added functionality around this behavior.
Using Spring Boot 2.6.0 and Jackson 2.13.0, the spring.jackson.default-leniency
application property can be set to false
to achieve the desired result.
spring.jackson.default-leniency: false
Starting with Jackson 2.13.0, setting the lenient
flag to false
causes causes dates with times to be rejected when the underlying type is a date without a time (jackson-modules-java8#212).
Spring Boot 2.6.0 added the spring.jackson.default-leniency
flag to configure the default leniency on the Spring Boot provided ObjectMapper
bean (spring-boot#27547).
Therefore, combining these two library versions, and utilizing the spring.jackson.default-leniency
flag achieves the desired result of rejecting dates with time components for LocalDate
values.
Spring Boot 2.5.x does not have an application property to set the default leniency of the Spring Boot provided ObjectMapper
bean. However, it is possible to customize this bean in other ways to set the default leniency. As noted above, this will achieve the desired result of rejecting dates with times in Jackson 2.13.x or later.
The most straightforward approach to setting the default leniency in a Spring Boot 2.5.x application is probably to use a custom Jackson2ObjectMapperBuilderCustomizer
bean to configure the ObjectMapper
:
@Configuration
public class CustomizedJacksonConfiguration {
@Bean
public Jackson2ObjectMapperBuilderCustomizer nonLenientObjectMapperBuilderCustomizer() {
return builder -> builder.postConfigurer(
objectMapper -> objectMapper.setDefaultLeniency(false));
}
}
As noted above, setting the lenient
flag to false
does not actually cause Jackson versions prior to 2.13 to reject values with a time part.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With