1

I am upgrading my spring boot application to spring boot 2.7.8 and Java 11. I getting different rest response of ZonedDateTime object after upgrade.

My request contain "2023-06-23T18:13:06.630Z[UTC]", and I am returning same request object as a Map key in response. But in response ending 0's from millisecond part getting trimmed "2023-06-23T18:13:06.63Z[UTC]".

Request:
{
    "dateList": [
       "2023-06-23T18:13:06.630Z[UTC]"
    ]
}

Response:
{
    "dateList": {
        "2023-06-23T18:13:06.63Z[UTC]": "2023-06-23T11:13:06.630-07:00"
    }
}

Did someone faced earlier this issue?

Any solution to this issue, As I am using as Map key of ZonedDateTime, I need to keep it consistent.

1 Answers1

1

This is a known issue with Jackson that affects the serialization of ZonedDateTime objects.

This issue is caused by the fact that Jackson by default uses Java's built-in DateTimeFormatter to serialize and deserialize dates and times, so this format does not preserve trailing zeros in milliseconds.

To fix this issue, you can configure Jackson to use a custom date/time format that preserves trailing zeros in milliseconds

I tried this and by creating a custome config for jackson:

@Configuration
public class JacksonConfig {

    @Value("${spring.jackson.date-format}")
    private String dateFormat;

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
        return builder -> {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
            builder.simpleDateFormat(dateFormat).serializers(new ZonedDateTimeSerializer(formatter));
            builder.deserializers(new ZonedDateTimeDeserializer(formatter));
        };
    }

    public static class ZonedDateTimeSerializer extends StdSerializer<ZonedDateTime> {

        private final DateTimeFormatter formatter;

        public ZonedDateTimeSerializer(DateTimeFormatter formatter) {
            super(ZonedDateTime.class);
            this.formatter = formatter;
        }

        @Override
        public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            gen.writeString(formatter.format(value));
        }
    }

    public static class ZonedDateTimeDeserializer extends StdDeserializer<ZonedDateTime> {

        private final DateTimeFormatter formatter;

        public ZonedDateTimeDeserializer(DateTimeFormatter formatter) {
            super(ZonedDateTime.class);
            this.formatter = formatter;
        }

        @Override
        public ZonedDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            String value = p.getValueAsString();
            return ZonedDateTime.parse(value, formatter);
        }
    }
}

P.S :Also you can use this formatter to format your ZonedDateTime objects before adding them to the map:

ZonedDateTime zdt = ZonedDateTime.parse("2023-06-23T18:13:06.630Z[UTC]");
String formatted = zdt.format(formatter);

Map<String, String> response = new HashMap<>();
response.put(formatted, zdt.toString());
Soheil Babadi
  • 562
  • 2
  • 4
  • 15
  • 1
    Thanks @Soheil for your answer, But this didn't help. I tried this solution, still getting same issue. – Ranjit Meher May 29 '23 at 06:55
  • I am facing this issue while Jackson serialize the rest API response, before serialization trailing 0 present, once serialized 0 from millisecond is getting truncated. – Ranjit Meher May 29 '23 at 07:02
  • could you please suggest which ${spring.jackson.date-format} you have used? – Ranjit Meher Jun 05 '23 at 17:09
  • @RanjitMeher I added P.S to my answer – Soheil Babadi Jun 05 '23 at 17:15
  • I can't change the MAP key data type as it has dependency in other application. and till my rest controller return Response point of line MAP is having the expected value. Once its reached to Spring library its and did serialization value getting changed. – Ranjit Meher Jun 05 '23 at 22:12