Skip to content

DurationDeserializer should use @JsonFormat.pattern (and config override) to support configurable ChronoUnit #184

@chisui

Description

@chisui

When deserializing DurationDeserializer treats all durations of number values as seconds and delegates string values to Duration.parse.

Versions

com.fasterxml.jackson.core:jackson-core:jar:2.11.2
com.fasterxml.jackson.core:jackson-databind:jar:2.11.2
com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.11.2
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.11.2
com.fasterxml.jackson.core:jackson-annotations:jar:2.11.2

Example

class A {
    @JsonFormat(pattern = "h")
    Duration dur;

    public static void main(String[] args) throws Exception {
        JsonMapper m = JsonMapper.builder()
                .addModule(new JavaTimeModule())
                .build();
        A a0 = m.readValue("{\"dur\":2}".getBytes(), A.class);
        System.out.println(a0.dur.equals(Duration.ofHours(2))); // should print "true" but prints "false

        A a1 = m.readValue("{\"dur\":\"2\"}".getBytes(), A.class);
        System.out.println(a1.dur.equals(Duration.ofHours(2))); // should print "true" but throws Exception
    }
}

The Exception thrown by the second readValue call:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.Duration` from String "2": Failed to deserialize java.time.Duration: (java.time.format.DateTimeParseException) Text cannot be parsed to a Duration
 at [Source: (byte[])"{"dur":"2"}"; line: 1, column: 8] (through reference chain: *****)

	at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1702)
	at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:947)
	at com.fasterxml.jackson.datatype.jsr310.deser.JSR310DeserializerBase._handleDateTimeException(JSR310DeserializerBase.java:129)
	at com.fasterxml.jackson.datatype.jsr310.deser.DurationDeserializer.deserialize(DurationDeserializer.java:92)
	at com.fasterxml.jackson.datatype.jsr310.deser.DurationDeserializer.deserialize(DurationDeserializer.java:43)
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:293)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:156)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4524)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3527)
        ...
Caused by: java.time.format.DateTimeParseException: Text cannot be parsed to a Duration
	at java.base/java.time.Duration.parse(Duration.java:417)
	at com.fasterxml.jackson.datatype.jsr310.deser.DurationDeserializer.deserialize(DurationDeserializer.java:90)
	... 70 more

Even though JsonFormat doesn't explicitly mention any jsr310 classes in its documentation they should still work with it. Especially since DurationDeserializer already respects JsonFormat#lenient.

Metadata

Metadata

Assignees

No one assigned

    Labels

    json-formatMissing handling of `@JsonFormat` property annotation

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions