javajacksonjava-timejackson-modulesjackson2

Jackson , java.time , ISO 8601 , serialize without milliseconds


I'm using Jackson 2.8 and need to communicate with an API that doesn't allow milliseconds within ISO 8601 timestamps.

The expected format is this: "2016-12-24T00:00:00Z"

I'm using Jackson's JavaTimeModule with WRITE_DATES_AS_TIMESTAMPS set to false.

But this will print milliseconds.

So I tried to use objectMapper.setDateFormat which didn't change anything.

My current workaround is this:

ObjectMapper om = new ObjectMapper();

DateTimeFormatter dtf = new DateTimeFormatterBuilder()
    .appendInstant(0)
    .toFormatter();

JavaTimeModule jtm = new JavaTimeModule();
jtm.addSerializer(Instant.class, new JsonSerializer<Instant>() {
    @Override
    public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        gen.writeString(dtf.format(value));
    }
});

om.registerModule(jtm);

I'm overriding the default serializer for Instant.class which works.


Is there any nice way using some configuration parameter to solve this?


Solution

  • Update:

    Just add a @JsonFormat annotation with the date format above the Instant property. It's very easy.

    In the case you have an ObjectMapper with the JavaTimeModule like next:

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    

    If you have a class with an Instant property, you should add the @JsonFormat annotation and put the date pattern which hasn't milliseconds. It would be like next:

    public static class TestDate {
    
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss", timezone = "UTC")
        Instant instant;
    
        //getters & setters
    }
    

    So if you serialize an object to Json it works perfectly:

    String json = mapper.writeValueAsString(testDate);
    System.out.println(json); 
    

    Output

    {"instant":"2016-11-10 06:03:06"}


    Old Answer. I don't know why but It doesn't work properly:

    You could use the Jackson2ObjectMapperBuilder to build it.

    You just need to add the dateFormat you want. It would be something like next:

    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    
    ObjectMapper mapper = Jackson2ObjectMapperBuilder
                .json()       
                .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) 
                .modules(new JavaTimeModule())
                .dateFormat(dateFormat)
                .build();