Skip to content

JsonIgnoreProperties(ignoreUnknown = true) does not work on field and method level #2627

@robotmrv

Description

@robotmrv

Expected Result:

com.fasterxml.jackson.annotation.JsonIgnoreProperties#ignoreUnknown should work on filed/getter level the same way as com.fasterxml.jackson.annotation.JsonIgnoreProperties#value works

Actual Result:

com.fasterxml.jackson.annotation.JsonIgnoreProperties#ignoreUnknown works only on Class level.
and fails with exception

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "extra" (class com.example.IgnoreUnknownTest$MyPojo), not marked as ignorable (one known property: "name"])
 at [Source: (String)"{"value": {"name": "my_name", "extra": "val"}, "type":"Json"}"; line: 1, column: 41] (through reference chain: com.example.IgnoreUnknownTest$MyPojoValue["value"]->com.example.IgnoreUnknownTest$MyPojo["extra"])

	at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
	at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1153)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
	at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:530)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:528)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:417)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1287)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4014)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3005)
	at com.example.IgnoreUnknownTest.shouldDeserializeWithUnknownProperties(IgnoreUnknownTest.java:17)

Test case

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.assertj.core.api.Assertions;
import org.junit.Test;

import java.beans.ConstructorProperties;
import java.io.IOException;

public class IgnoreUnknownTest {

    @Test
    public void shouldDeserializeWithUnknownProperties() throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "{\"value\": {\"name\": \"my_name\", \"extra\": \"val\"}, \"type\":\"Json\"}";
        MyPojoValue value = objectMapper.readValue(json, MyPojoValue.class);
        Assertions.assertThat(value).isNotNull();
        Assertions.assertThat(value.getValue()).isNotNull();
        Assertions.assertThat(value.getValue().getName()).isEqualTo("my_name");
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    abstract static class GenericHolder<T> {
        @JsonIgnoreProperties(ignoreUnknown = true)// <-- this does not work
//        @JsonIgnoreProperties("extra") //with this test passes
        private final T value;

        public GenericHolder(T value) {
            this.value = value;
        }

        public T getValue() {
            return value;
        }

        @Override
        public String toString() {
            return getClass().getSimpleName() + "{" +
                    "value=" + value +
                    '}';
        }
    }

    static class MyPojoValue extends GenericHolder<MyPojo> {
        @ConstructorProperties("value")
        public MyPojoValue(MyPojo value) {
            super(value);
        }
    }

    static class MyPojo {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return getClass().getSimpleName() + "{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
}

Jackson versions:

com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-databind:2.9.10.2

reproduces with:
com.fasterxml.jackson.core:jackson-annotations:2.10.3-SNAPSHOT
com.fasterxml.jackson.core:jackson-core:2.10.3-SNAPSHOT
com.fasterxml.jackson.core:jackson-databind:2.10.3-SNAPSHOT

com.fasterxml.jackson.core:jackson-annotations:2.11.0-SNAPSHOT
com.fasterxml.jackson.core:jackson-core:2.11.0-SNAPSHOT
com.fasterxml.jackson.core:jackson-databind:2.11.0-SNAPSHOT

com.fasterxml.jackson.core:jackson-annotations:3.0-SNAPSHOT
com.fasterxml.jackson.core:jackson-core:3.0.0-SNAPSHOT
com.fasterxml.jackson.core:jackson-databind:3.0.0-SNAPSHOT

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions