4

The following code works fine:

    // works
public class MyClass {

  @JsonSerialize(using = LocalDateTimeSerializer.class)
  @JsonDeserialize(using = LocalDateTimeDeserializer.class)
  private LocalDateTime startDate;

  @JsonSerialize(using = LocalDateTimeSerializer.class)
  @JsonDeserialize(using = LocalDateTimeDeserializer.class)
  private LocalDateTime endDate;

  @JsonSerialize(using = LocalDateTimeSerializer.class)
  @JsonDeserialize(using = LocalDateTimeDeserializer.class)
  private LocalDateTime otherDate;

  @JsonSerialize(using = LocalDateTimeSerializer.class)
  @JsonDeserialize(using = LocalDateTimeDeserializer.class)
  private LocalDateTime someMoreDate;

...}

But I don't like the repeating aspect of writing the exact same annotations for each Date field.

What I tried:

// does not work

  @JsonSerialize(using = LocalDateTimeSerializer.class)
  @JsonDeserialize(using = LocalDateTimeDeserializer.class)
public class MyClass {


  private LocalDateTime startDate;
  private LocalDateTime endDate;
  private LocalDateTime otherDate;
  private LocalDateTime someMoreDate;

...}

Trying this leads to the error:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: 
class MyClass cannot be cast to class java.time.LocalDateTime (MyClass is in unnamed module of loader 'app'; java.time.LocalDateTime is in module java.base of loader 'bootstrap') (through reference chain: java.util.HashMap["ctxData"])

Configuration of spring application was extended by:

@Bean(name = "OBJECT_MAPPER_BEAN")
  public ObjectMapper jsonObjectMapper() {
    return Jackson2ObjectMapperBuilder.json()
        .serializationInclusion(JsonInclude.Include.NON_NULL)
        .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
        .modules(new JavaTimeModule())
        .build();
  }

Any ideas what I can try?

DerBenniAusA
  • 727
  • 1
  • 7
  • 13
  • For `java.time` stuff you can just add a module to your ObjectMapper and then you don't need any annotations `objectMapper.registerModule(new JavaTimeModule());` – Michael Apr 23 '19 at 12:19
  • I added to the configuration of spring application the bean above. Is this correct? – DerBenniAusA Apr 23 '19 at 12:23

2 Answers2

2

If you are using jackson to manage json serialization/deserialization with Spring you can configure ObjectMapper globally :

@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();

    builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME));
    builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));

    return builder;
}
Michał Krzywański
  • 15,659
  • 4
  • 36
  • 63
  • I like the approach, but it seems that I dont have the right setup yet. If I remove the field annotations and define the globally mapper, it doesnt work anymore – DerBenniAusA Apr 23 '19 at 13:03
1

This will use LocalDateTimeSerializer/LocalDateTimeDeserializer to serialize/deserializes the whole MyClass, not the time fields of it.

@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
public class MyClass {

Instead, you can just register JavaTimeModule to your ObjectMapper.

xingbin
  • 27,410
  • 9
  • 53
  • 103