Skip to content

Unable to ignore properties when deserializing. TokenFilter seems broken #700

@xiazuojie

Description

@xiazuojie

We have the following JSON generated by another JSON library that includes property @type to indicate value types. We want Jackson to ignore @type properties (both root and inner ones) when deserializing the data to Map<Long, Map<Long, Long>>.

{
   "@type":"java.util.LinkedHashMap",
   "111":{
      "@type":"java.util.LinkedHashMap",
      "1":11,
      "2":22
   }
}

What we have tried so far:

  • ObjectReader.withoutAttribute("@type")
  • ObjectMapper.addMixIn
  • TokenFilter
  • upgrade Jackson to latest version 2.12.3

None of the above gets what we want.
The closest result we've got is by using TokenFilter. However, there's always something broker no matter what combination of TokenFilter options we choose:

  • TokenFilter#includeProperty returning this or TokenFilter#INCLUDE_ALL
  • all TokenFilter.Inclusion enums for FilteringParserDelegate#_inclusion
  • FilteringParserDelegate#_allowMultipleMatches true or false

It seems TokenFilter is broken. The following is our test case.

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.filter.FilteringParserDelegate;
import com.fasterxml.jackson.core.filter.TokenFilter;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import org.junit.Test;

import java.util.Map;

import static org.junit.Assert.assertEquals;

public class IgnorePropertyTest {
    private final ObjectMapper mapper = new ObjectMapper();
    private final String LONG_INNER_MAP_WITH_AUTO_TYPE = "{\"@type\":\"java.util.LinkedHashMap\",\"111\":{\"@type\":\"java.util.LinkedHashMap\",\"1\":11,\"2\":22}}";

    @Test
    public void testTokenFilter() throws Exception {
        final TokenFilter tokenFilter = new TokenFilter() {
            @Override
            public TokenFilter includeProperty(String name) {
                if ("@type".equals(name)) {
                    return null;
                }
                return this;
            }
        };
        JsonParser jsonParser = new FilteringParserDelegate(
                mapper.createParser(LONG_INNER_MAP_WITH_AUTO_TYPE),
                tokenFilter,
                TokenFilter.Inclusion.INCLUDE_ALL_AND_PATH,
                true);
        Map<Long, Map<Long, Long>> data = mapper.readValue(jsonParser, new TypeReference<Map<Long, Map<Long, Long>>>() {});
        check(data);
    }

    @Test
    public void testReader() throws Exception {
        ObjectReader reader = mapper.readerFor(new TypeReference<Map<Long, Map<Long, Long>>>() {});
        Map<Long, Map<Long, Long>> data = reader.withoutAttribute("@type").readValue(LONG_INNER_MAP_WITH_AUTO_TYPE);
        check(data);
    }

    @Test
    public void testMixin() throws Exception {
        ObjectMapper mp = mapper.addMixIn(Map.class, MixIn.class);
        Map<Long, Map<Long, Long>> data = mp.readValue(LONG_INNER_MAP_WITH_AUTO_TYPE, new TypeReference<Map<Long, Map<Long, Long>>>() {});
        check(data);
    }

    @JsonIgnoreProperties({"@kind"})
    private static abstract class MixIn {
    }

    private void check(Map<Long, Map<Long, Long>> data) {
        assertEquals(1, data.size());
        assertEquals(2, data.get(111L).size());
        assertEquals(11L, (long)data.get(111L).get(1L));
        assertEquals(22L, (long)data.get(111L).get(2L));
    }
}

Jackson version: 2.12.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions