使用带有Jackson JSON解析后端的Spring RestControllers,前端使用AngularJS。我正在寻找一种有效的方法让Jackson序列化一个Instant作为纪元毫秒,以便随后使用JavaScript代码。 (在浏览器方面,我希望通过Angular Date Filter:{{myInstantVal | date:'short' }}
为我所需的日期格式提供时代ms。)
在Java方面,杰克逊将使用的吸气剂只是:
public Instant getMyInstantVal() { return myInstantVal; }
序列化不会按原样运行,因为jackson-datatype-jsr310默认情况下不会为Instant返回Epoch毫秒。我看着将@JsonFormat添加到上面的getter中以将Instant变形为前端可以使用的东西,但它遇到两个问题:(1)我可以提供它的模式显然仅限于SimpleDateFormat,它没有'提供“epoch毫秒”选项,以及(2)当我尝试将Instant作为格式化日期发送到浏览器时,Jackson会抛出异常,因为@JsonFormat注释需要Instants的TimeZone属性,我不这样做希望硬编码,因为它会因用户而异。
到目前为止,我的解决方案(并且工作正常)是使用@JsonGetter创建替换的getter,这会导致Jackson使用此方法来序列化myInstantVal
:
@JsonGetter("myInstantVal")
public long getMyInstantValEpoch() {
return myInstantVal.toEpochMilli();
}
这是正确的方法吗?或者是否有一个很好的注释我错过了我可以使用getMyInstantVal()所以我不必创建这些额外的方法?
答案 0 :(得分:11)
您只需阅读链接到的自述文件。强调我的:
如果启用了SerializationFeature#WRITE_DATES_AS_TIMESTAMPS功能,则大多数JSR-310类型被序列化为数字(适当时为整数或小数),否则将以标准ISO-8601字符串表示形式序列化。
[...]
时间戳的粒度通过配套功能SerializationFeature#WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS和DeserializationFeature#READ_DATE_TIMESTAMPS_AS_NANOSECONDS来控制。对于序列化,时间戳写为小数(小数),其中数字为秒,小数为小数秒,如果启用WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS(默认情况下),分辨率可以为纳秒,具体取决于基础JDK实现。 如果禁用WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,则时间戳将写为整数毫秒。
答案 1 :(得分:1)
添加JB的答案,覆盖Spring MVC的默认JSON解析器,从Instant(以及其他拥有它们的Java 8日期对象)中剥离纳秒:
在mvc:annotation-driven元素中,指定您将覆盖默认的JSON消息转换器:
<mvc:annotation-driven validator="beanValidator">
<mvc:message-converters register-defaults="true">
<beans:ref bean="jsonConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
(默认情况下,寄存器默认值为true,很可能是您希望保持Spring按原样配置的其他转换器。
覆盖MappingJackson2HttpMessageConverter,如下所示:
<beans:bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<beans:property name="objectMapper">
<beans:bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<beans:property name="featuresToDisable">
<beans:array>
<util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS"/>
</beans:array>
</beans:property>
</beans:bean>
</beans:property>
步骤#1非常重要,因为Spring MVC将忽略已配置的MJ2HMC对象而支持其自己的默认对象。
部分H / T this SO帖子。
答案 2 :(得分:0)
在Instant属性的JSON响应中返回纪元毫秒的简单方法如下:
@JsonFormat(shape = JsonFormat.Shape.NUMBER, timezone = "UTC")
private Instant createdAt;
这将导致以下响应:
{
...
"createdAt": 1534923249,
...
}