#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?