jackson-databind: If the property is `required`, the `absentValue` is ignored and a `MismatchedInputException` is thrown.

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

If the property is required, the absentValue is ignored and a MismatchedInputException is thrown.

Version Information

2.15.3

Reproduction

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import org.junit.jupiter.api.Test;

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class GitHubXXX {
    static class MyDeser extends StdDeserializer<String> {
        public MyDeser() {
            super(String.class);
        }

        @Override
        public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
            return p.getValueAsString();
        }

        @Override
        public Object getAbsentValue(DeserializationContext ctxt) {
            return "absent";
        }
    }

    static class Dto {
        private final String foo;
        private final String bar;

        @JsonCreator
        Dto(
                @JsonProperty(value = "foo", required = false)
                @JsonDeserialize(using = MyDeser.class)
                String foo,
                @JsonDeserialize(using = MyDeser.class)
                @JsonProperty(value = "bar", required = true)
                String bar
        ) {
            this.foo = foo;
            this.bar = bar;
        }
    }

    @Test
    void test() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();

        Dto r1 = mapper.readValue("{\"bar\":\"value\"}", Dto.class);
        assertEquals("absent", r1.foo);
        assertEquals("value", r1.bar);

        // -> throws MismatchedInputException: Missing required creator property 'bar' (index 1)
        Dto r2 = mapper.readValue("{}", Dto.class);
        assertEquals("absent", r2.foo);
        assertEquals("absent", r2.bar);
    }
}

Expected behavior

If absentValue returns a non-null value, then processing should continue.

Additional context

By organizing these priorities, we believe that the deserialization process in kotlin-module can be written easily and without differences in behavior. https://github.com/FasterXML/jackson-module-kotlin/blob/fc47a94e81586990dd19d05087580652c14b7f7a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt#L75-L89

About this issue

  • Original URL
  • State: closed
  • Created 8 months ago
  • Comments: 16 (16 by maintainers)

Most upvoted comments

I see, LGTM. Personally, I feel that it would be even better if you had a comment to add to that.

True, added such comment accordingly. 🙏🏼

Will close, although am willing to hear counter-arguments if there are some.