Issue
Using Spring RestControllers with Jackson JSON parsing backend, with AngularJS on front end. I'm looking for an efficient way to have Jackson serialize an Instant as the epoch milliseconds for subsequent convenient usage with JavaScript code. (On the browser side I wish to feed the epoch ms through Angular's Date Filter: {{myInstantVal | date:'short' }}
for my desired date format.)
On the Java side, the getter that Jackson would use is simply:
public Instant getMyInstantVal() { return myInstantVal; }
Serialization wouldn't work as-is, because the jackson-datatype-jsr310 doesn't return Epoch milliseconds by default for an Instant. I looked at adding @JsonFormat to the above getter to morph the Instant into something the front-end can use, but it suffers from two problems: (1) the pattern I can supply it is apparently limited to SimpleDateFormat which doesn't provide an "epoch milliseconds" option, and (2) when I tried to send the Instant as a formatted date to the browser instead, Jackson throws an exception because the @JsonFormat annotation requires a TimeZone attribute for Instants, something I don't wish to hardcode as it would vary from user to user.
My solution so far (and it's working fine) is to create a replacement getter using @JsonGetter, which causes Jackson to use this method instead to serialize myInstantVal
:
@JsonGetter("myInstantVal")
public long getMyInstantValEpoch() {
return myInstantVal.toEpochMilli();
}
Is this the proper way of doing this? Or is there a nice annotation I'm missing that I can put on getMyInstantVal() so I won't have to create these additional methods?
Solution
You just need to read the README that you linked to. Emphasis mine:
Most JSR-310 types are serialized as numbers (integers or decimals as appropriate) if the SerializationFeature#WRITE_DATES_AS_TIMESTAMPS feature is enabled, and otherwise are serialized in standard ISO-8601 string representation.
[...]
Granularity of timestamps is controlled through the companion features SerializationFeature#WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS and DeserializationFeature#READ_DATE_TIMESTAMPS_AS_NANOSECONDS. For serialization, timestamps are written as fractional numbers (decimals), where the number is seconds and the decimal is fractional seconds, if WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS is enabled (it is by default), with resolution as fine as nanoseconds depending on the underlying JDK implementation. If WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS is disabled, timestamps are written as a whole number of milliseconds.
Answered By - JB Nizet
Answer Checked By - Mildred Charles (JavaFixing Admin)