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.