I found a way to do it without writing a custom deserializer, but it'll require some modifications.
First, the LocalDateDeserializer
accepts a custom DateTimeFormatter
. So, we need to create a formatter that accepts an epoch millis. I did this by joining the INSTANT_SECONS
and MILLI_OF_SECOND
fields:
// formatter that accepts an epoch millis value
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
// epoch seconds
.appendValue(ChronoField.INSTANT_SECONDS, 1, 19, SignStyle.NEVER)
// milliseconds
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
// create formatter, using UTC as timezone
.toFormatter().withZone(ZoneOffset.UTC);
I also set the formatter with UTC zone, so it won't be affected by timezones and DST changes.
Then, I've created the deserializer and registered in my ObjectMapper
:
ObjectMapper mapper = new ObjectMapper();
JavaTimeModule module = new JavaTimeModule();
// add the LocalDateDeserializer with the custom formatter
module.addDeserializer(LocalDate.class, new LocalDateDeserializer(formatter));
mapper.registerModule(module);
I also had to remove the annotation from the birthday
field (because the annotation seems to override the module configuration):
public class FbProfile {
long id;
// remove @JsonDeserialize annotation
LocalDate birthday;
}
And now the big issue: as the DateTimeFormatter
accepts only String
as input, and the JSON contains a number in birthday
field, I had to change the JSON:
{
"id" : "1",
"birthday" : "401280850089"
}
Note that I changed birthday
to a String
(put the value between quotes).
With this, the LocalDate
is read from JSON correctly:
FbProfile value = mapper.readValue(json, FbProfile.class);
System.out.println(value.getBirthday()); // 1982-09-19
Notes:
- I couldn't find a way to pass the number directly to the formatter (as it takes only
String
as input), so I had to change the number to be a String
. If you don't want to do that, then you'll have to write a custom converter anyway.
- You can replace
ZoneOffset.UTC
with any timezone you want (even ZoneId.systemDefault()
), it'll depend on what your application needs. But as told in @Ole V.V.'s comment, the timezone might cause the date to change.