Дезаминирование LocalDateTime с помощью модуля Jackson JSR310
Я использую библиотеку, описанную страницу Jackson Datatype JSR310, но мне все еще трудно заставить ее работать.
Я сконфигурировал следующий bean:
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
return mapper;
}
Когда я вызываю свой REST API, выходной формат даты равен yyyy-MM-dd'T'HH:ss.SSSSSS
, например. 2015-04-11T00:10:38.905847
. Это очень удобно обрабатывает мой код AngularJS.
Когда я хочу отправить что-то в REST API, дата отправляется как yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
, например. 2015-04-09T08:30:00.000Z
Джексон продолжает жаловаться на "Z" в конце. Если я смотрю на LocalDateTimeDeserializer
в документации, он использует DateTimeFormatter.ISO_LOCAL_DATE_TIME
, который кипит до ISO_LOCAL_DATE'T'ISO_LOCAL_TIME
, и он упоминает, что у него нет зоны переопределения.
Итак, я решил, что должен установить DateFormat
в ObjectMapper
, который я создаю:
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
return mapper;
}
Но это ничего не делает. Я изменил его на что-то простое, как yyyy-MM-dd
, но сериализованная дата осталась в предыдущем формате, и десериализация тоже не затронута.
Что я делаю неправильно здесь, чтобы заставить это работать? Формат даты в моем JavaScript-коде, насколько я знаю, формат ISO 8601...
Ответы
Ответ 1
Не нужно писать собственный сериализатор. Достаточно использовать значение по умолчанию, но создавая экземпляр с другим форматом (time_zone
one), так что большая часть просто вырезается:
new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)
В моем случае у меня есть contextResolver
, как это для достижения на уровне конфигурации:
@Service
@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperContextResolver() {
mapper = new ObjectMapper();
JavaTimeModule javaTimeModule=new JavaTimeModule();
// Hack time module to allow 'Z' at the end of string (i.e. javascript json's)
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));
mapper.registerModule(javaTimeModule);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
Ответ 2
На данный момент LocalDateTimeDeserializer
, похоже, не уважает формат даты, установленный для объекта mapper.
Чтобы сделать это, вы можете переопределить LocalDateTimeDeserializer
или переключиться на использование ZoneDateTime
, который обрабатывает "Z" char в конце.
Вот пример:
public class Java8DateFormat {
public static void main(String[] args) throws IOException {
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JSR310Module());
// mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
final String date = mapper.writeValueAsString(new Date());
System.out.println(date);
System.out.println(mapper.readValue(date, ZonedDateTime.class));
}
}
Вывод:
"2015-04-11T18:24:47.815Z"
2015-04-11T18:24:47.815Z[GMT]
Ответ 3
Спящий режим 4, Spring 4 - REST WS, Клиент - Spring Загрузка 1.5.2. В моем случае я использовал в классе Entity ZonedDateTime для сопоставления Timestamp в базе данных. Спящий режим, а также Spring Boot REST отлично работают. Я должен добавлять библиотеки только в файл pom:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
Итак, я полагаю, что этот конвертер реализован внутри Spring для LocalDateTime. The jackson.version является последним.