Возможно ли упростить аннотации @JsonSerialize?

#java #datetime #jackson-databind #jsonserializer #localdate

#java #дата и время #джексон-привязка данных #jsonserializer #localdate

Вопрос:

Следующий код работает нормально:

     // 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;

...}
  

Но мне не нравится повторяющийся аспект написания одних и тех же аннотаций для каждого поля даты.

Что я пробовал:

 // 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;

...}
  

Попытка этого приводит к ошибке:

 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"])
  

Конфигурация приложения Spring была расширена за счет:

 @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();
  }
  

Есть идеи, что я могу попробовать?

Комментарии:

1. Для java.time материала вы можете просто добавить модуль в свой ObjectMapper, и тогда вам не нужны никакие аннотации objectMapper.registerModule(new JavaTimeModule());

2. Я добавил в конфигурацию приложения Spring приведенный выше компонент. Правильно ли это?

Ответ №1:

Если вы используете jackson для управления сериализацией / десериализацией json с помощью Spring, вы можете настроить ObjectMapper глобально :

 @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;
}
  

Комментарии:

1. Мне нравится подход, но, похоже, у меня пока нет правильной настройки. Если я удалю аннотации полей и определю глобальный преобразователь, он больше не будет работать

Ответ №2:

Это будет использовать LocalDateTimeSerializer / LocalDateTimeDeserializer для сериализации / десериализации всего MyClass , а не его временных полей.

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

Вместо этого вы можете просто зарегистрироваться JavaTimeModule в своем ObjectMapper .

Комментарии:

1. могу ли я выполнить вызов register в @Bean?