Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
In Spring Boot 1.2.3.RELEASE with fasterxml what is the correct way of serializing and de-serializing a
LocalDate
field to ISO date formatted string?
I've tried:
spring.jackson.serialization.write-dates-as-timestamps:false
in application.properties file,
including
jackson-datatype-jsr310
in project and then using
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
annotation
and
@DateTimeFormat(iso=ISO.DATE)
annotation,
adding
Jsr310DateTimeFormatAnnotationFormatterFactory
as formatter with:
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory());
None of the above helped.
and then following annotations helped:
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate birthday;
Update: if you are using Spring Boot 2.*, the dependency is already included via one of the "starters".
–
–
–
In my Spring Boot 2 applications
@JsonFormat
annotation is used in REST controllers when (de)serializing JSON data.
@DateTimeFormat
annotation is used in other controllers ModelAttribute
s when (de)serializing String data.
You can specify both on the same field (useful if you share DTO between JSON and Thymeleaf templates):
@JsonFormat(pattern = "dd/MM/yyyy")
@DateTimeFormat(pattern = "dd/MM/yyyy")
private LocalDate birthdate;
Gradle dependency:
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-json'
I hope this is all configuration you need for custom Date/Time formatting in Spring Boot 2.x apps.
For Spring Boot 1.x apps, specify additional annotations and dependency:
@JsonFormat(pattern = "dd/MM/yyyy")
@DateTimeFormat(pattern = "dd/MM/yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate birthDate;
// or
@JsonFormat(pattern = "dd/MM/yyyy HH:mm")
@DateTimeFormat(pattern = "dd/MM/yyyy HH:mm")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime birthDateTime;
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.8'
Be aware that your API will throw "JSON parse error" if somebody sends a date in a wrong format. Mapping example:
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate releaseDate;
Exception example:
HttpMessageNotReadableException
: JSON parse error: Cannot deserialize value of type java.time.LocalDate
from String "2002": Failed to deserialize java.time.LocalDate
: (java.time.format.DateTimeParseException
) Text '2002' could not be parsed at index 4; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException
: Cannot deserialize value of type java.time.LocalDate
from String "2002": Failed to deserialize java.time.LocalDate
: (java.time.format.DateTimeParseException
) Text '2002' could not be parsed at index 4
If you want to use a custom Java Date formatter, add the @JsonFormat
annotation.
@JsonFormat(pattern = "dd/MM/yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate birthdate;*
–
Actually, it works if you just specify the dependency in the pom.xml.
With this, all my LocalDate fields automatically use the ISO format, no need to annotate them:
<!-- This is enough for LocalDate to be deserialized using ISO format -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
Tested on Spring Boot 1.5.7.
Instead of specifying the serializer/deserializer for all your LocalDate attributes, you might be interested in registering it globally. You need to override the configuration of the default ObjectMapper used by Spring for serialization/deserialization. Here is an example:
@Configuration
public class ObjectMapperConfiguration {
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// Registro global do serializer/deserializer para datas sem horário
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer());
simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
mapper.registerModule(simpleModule);
return mapper;
This way, Jackson will always use the specified serializer/deserializer for the data type defined, without the need to annotate your classes attributes.
Info: you must add the jackson-databind dependency to your pom.xml to have the custom serializer/deserializer code feature:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
DateTimeFormatter localDateFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
builder.serializerByType(LocalDate.class, new LocalDateSerializer(localDateFormatter));
builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(localDateFormatter));
DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(localDateTimeFormatter));
builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(localDateTimeFormatter));
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.