Andrew Tobilko Andrew Tobilko - 6 months ago 147
Java Question

LocalDateTime - deserialization with LocalDateTime.parse

I have the field

initiationDate
which serialises by
ToStringSerializer
class to ISO-8601 format.

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


When I receive the following JSON,

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


I want to deserialize it by
LocalDateTime.parse(CharSequence text)
factory method. All my attempts ended with
com.fasterxml.jackson.databind.JsonMappingException
:


Can not instantiate value of type [simple type, class
java.time.LocalDateTime
] from
String
value (
'2016-05-11T17:32:20.897'
); no single-
String
constructor/factory method


How do I achieve that? How can I specify factory method?




EDIT:

The problem has been solved by including jackson-datatype-jsr310 module to the project and using
@JsonDeserialize
with
LocalDateTimeDeserializer
.

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

Answer

Vanilla Jackson doesn't have a way to deserialize a LocalDateTime object from any JSON string value.

You have a few options. You can create and register your own JsonDeserializer which will use 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;

Or you can add Jackson's java.time extension to your classpath and register the appropriate Module with your ObjectMapper.

objectMapper.registerModule(new JavaTimeModule());

and let Jackson do the conversion for you. Internally, this uses LocalDateTime#parse with one of the standard formats. Fortunately, it supports values like

2016-05-11T17:32:20.897

out of the box.

Comments