FasterXML / jackson-modules-java8

Set of support modules for Java 8 datatypes (Optionals, date/time) and features (parameter names)
Apache License 2.0
401 stars 117 forks source link

Add customization option for LocalDateTime handling of seconds and nanos #117

Open steghio opened 5 years ago

steghio commented 5 years ago

Hi all,

as seen in https://github.com/FasterXML/jackson-modules-java8/blob/master/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateTimeSerializer.java method _serializeAsArrayContents line 112, if seconds or nanos are set to 0 in the LocalDateTime object being serialized, they will NOT be included into the resulting JSON.

I understand this might be trying to follow what its toString https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#toString does, but it is not convenient when senders and receivers either do not understand the LocalDateTime specification or are unable to handle it properly.

Please add a customization option to allow sending seconds and nanos even when set to 0, the only current workaround is to implement a custom serializer and add it to a custom mapper to be passed in whatever configuration needs it, which is not really convenient:

public static class LocalDateTimeWithSecondsSerializer extends StdSerializer<LocalDateTime> {

        public LocalDateTimeWithSecondsSerializer() {
            super(LocalDateTime.class);
        }

        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            gen.writeStartArray();
            gen.writeNumber(value.getYear());
            gen.writeNumber(value.getMonthValue());
            gen.writeNumber(value.getDayOfMonth());
            gen.writeNumber(value.getHour());
            gen.writeNumber(value.getMinute());
            gen.writeNumber(value.getSecond());
            gen.writeEndArray();
        }
    }

public static class CustomEntityMapper implements EntityMapper {

        private final ObjectMapper objectMapper;

        public CustomEntityMapper() {

            SimpleModule localDateTimeWithSecondsSerializerModule = new SimpleModule();
            localDateTimeWithSecondsSerializerModule.addSerializer(new LocalDateTimeWithSecondsSerializer());

            objectMapper = new ObjectMapper()
                              .registerModule(new JavaTimeModule())
                              .registerModule(localDateTimeWithSecondsSerializerModule)
                              .registerModule(new Jdk8Module());

            objectMapper.findAndRegisterModules();
        }

        @Override
        public String mapToString(Object object) throws IOException {
            return objectMapper.writeValueAsString(object);
        }

        @Override
        public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
            return objectMapper.readValue(source, clazz);
        }
    }

Thanks and cheers