LocalDateTime - десериализация с помощью LocalDateTime.parse

У меня есть поле initiationDate, которое сериализуется классом ToStringSerializer в формате ISO-8601.

@JsonSerialize(using = ToStringSerializer.class)
private LocalDateTime initiationDate;

Когда я получаю следующий JSON,

...
"initiationDate": "2016-05-11T17:32:20.897",
...

Я хочу десериализовать его методом LocalDateTime.parse(CharSequence text) factory. Все мои попытки закончились с com.fasterxml.jackson.databind.JsonMappingException:

Невозможно создать значение типа [simple type, class java.time.LocalDateTime] из String value ('2016-05-11T17:32:20.897'); no single-String конструктор /factory метод

Как мне это достичь? Как я могу указать метод factory?


ИЗМЕНИТЬ:

Проблема решена путем включения модуля jackson-datatype-jsr310 в проект и использования @JsonDeserialize с LocalDateTimeDeserializer.

@JsonSerialize(using = ToStringSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime initiationDate;

Ответ 1

У Vanilla Jackson нет способа десериализовать a LocalDateTime объект из любого строкового значения JSON.

У вас есть несколько вариантов. Вы можете создать и зарегистрировать свой собственный JsonDeserializer, который будет использовать LocalDateTime#parse.

class ParseDeserializer extends StdDeserializer<LocalDateTime> {
    public ParseDeserializer() {
        super(LocalDateTime.class);
    }

    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        return LocalDateTime.parse(p.getValueAsString()); // or overloaded with an appropriate format
    }
}
...
@JsonSerialize(using = ToStringSerializer.class)
@JsonDeserialize(using = ParseDeserializer.class)
private LocalDateTime initiationDate;

Или вы можете добавить Jackson java.time extension в свой путь к классам и зарегистрировать соответствующий Module с помощью ObjectMapper.

objectMapper.registerModule(new JavaTimeModule());

и пусть Джексон сделает для вас конверсию. Внутри это использует LocalDateTime#parse с одним из стандартных форматов. К счастью, он поддерживает такие значения, как

2016-05-11T17:32:20.897

из коробки.

Ответ 2

Для тех, кто хочет проанализировать пользовательский формат даты и времени.

1) Добавить зависимость

compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.8"

2) Аннотации Json с форматом даты и времени

public class ClientRestObject {

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime timestamp;

}

3) Зарегистрируйте модуль Java8 в ObjectMapper

private static ObjectMapper buildObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    //To parse LocalDateTime
    objectMapper.registerModule(new JavaTimeModule());
    return objectMapper;
}