Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot LocalDate field serialization and deserialization

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.

like image 285
aycanadal Avatar asked Jun 16 '15 14:06

aycanadal


1 Answers

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 ModelAttributes 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

like image 177
naXa Avatar answered Sep 22 '22 07:09

naXa