Force Milliseconds When Serialized Instantly to ISO8601 using Jackson

I have some questions related to serializing JSON using Jackson in a project where I use Spring Boot 2.0.0.M6, Spring Framework 5.0.1.RELEASEand Jackson 2.9.2.

I set the following Jackson related settings in application.properties:

spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false

Serialization works mostly as needed. However, I noticed that Jackson disables milliseconds if they are 000.

Test 1: Serializing Instant with milliseconds set to 000:

  • Initialize an instant field using Instant.parse("2017-09-14T04:28:48.000Z")
  • Serialize it with Jackson
  • The output will be "2017-09-14T04:28:48Z"

Test 2: Instant Serialization with milliseconds set to not 000:

  • Initialize instant field with Instant.parse("2017-09-14T04:28:48.100Z")
  • Serialize it with Jackson
  • The output will be "2017-09-14T04:28:48.100Z"

Questions

  • Is this design behavior?
  • Is there anything I can do to force serialization 000?
+10
source share
3 answers

There, Jackson seems to have an open question here *. This link contains two workarounds

Workaround 1

 ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());
    SimpleModule module = new SimpleModule();
    module.addSerializer(ZonedDateTime.class, new JsonSerializer<ZonedDateTime>() {
        @Override
        public void serialize(ZonedDateTime zonedDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            jsonGenerator.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZZ").format(zonedDateTime));
        }
    });
    objectMapper.registerModule(module);
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

Workaround 2

JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(ZonedDateTime.class,
  new ZonedDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")));
ObjectMapper mapper = new ObjectMapper().registerModule(javaTimeModule);

* The link does not work because they are deprecated FasterXML / jackson-datatype-jsr310 and moved it to jackson-modules-java8 . See https://github.com/FasterXML/jackson-modules-java8/issues/76.

+3
source

, , . Instant.

final ObjectMapper mapper = new ObjectMapper();
final JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(Instant.class, new KeepMillisecondInstantSerializer());
mapper.registerModule(javaTimeModule);

public class KeepMillisecondInstantSerializer extends JsonSerializer<Instant> {

    private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
            .withZone(ZoneId.of("UTC"));

    @Override
    public void serialize(final Instant instant, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException {
        final String serializedInstant = dateTimeFormatter.format(instant);
        jsonGenerator.writeString(serializedInstant);
    }
}

, Instant.toString() Instant . fooobar.com/questions/713617/....

+1

, :

ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule module = new JavaTimeModule();
module.addSerializer(Instant.class, new InstantSerializerWithMilliSecondPrecision());
objectMapper.registerModule(module);

InstantSerializerWithMilliSecondPrecision :

public class InstantSerializerWithMilliSecondPrecision extends InstantSerializer {

    public InstantSerializerWithMilliSecondPrecision() {
        super(InstantSerializer.INSTANCE, false, new DateTimeFormatterBuilder().appendInstant(3).toFormatter());
    }
}

. : 2019-09-27T02: 59: 59.000Z

0

Source: https://habr.com/ru/post/1689871/


All Articles