Spring uses Jackson's InstantSerializer to write out my Instant fields like this:
now: "2021-04-07T10:51:53.043320Z"
I don't want the nanoseconds, though - just the milliseconds. I guessed that setting the application property
spring.jackson.serialization.write-date-timestamps-as-nanoseconds=false
would achieve this, but it makes no difference.
How can I tell Spring/Jackson to omit the nanoseconds when serializing Instants?
(I'm using Spring Boot 2.2.11.RELEASE)
Update
I eventually got it work, based on this answer. I had to use the deprecated JSR310Module instead of JavaTimeModule, and override the createContextual(...) method to force it to always use my serializer.
@Bean
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
JSR310Module jsr310Module = new JSR310Module();
jsr310Module.addSerializer(Instant.class, new MyInstantSerializer());
objectMapper.registerModule(jsr310Module);
return objectMapper;
}
private static class MyInstantSerializer extends InstantSerializer {
public MyInstantSerializer() {
super(InstantSerializer.INSTANCE, false, false,
new DateTimeFormatterBuilder().appendInstant(3).toFormatter());
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
return this;
}
}
And this works too (based on Volodya's answer below):
@Bean
public Jackson2ObjectMapperBuilderCustomizer addCustomTimeSerialization() {
return jacksonObjectMapperBuilder ->
jacksonObjectMapperBuilder.serializerByType(Instant.class, new JsonSerializer<Instant>() {
private final DateTimeFormatter formatter =
new DateTimeFormatterBuilder().appendInstant(3).toFormatter();
@Override
public void serialize(
Instant instant, JsonGenerator generator, SerializerProvider provider) throws IOException {
generator.writeString(formatter.format(instant));
}
});
}