Search code examples
androidjsonjacksonpojo

Selective usage of @JsonCreator


I've got a POJO such as

public class Category {
    public Collection<Item> items;
    public static class Item {
        public String firstAttribute;
        public int value;
    }
}

I'm converting from json input to POJO(Category) with the following:

JsonNode results = mapper.readTree(connection.getInputStream());

mapper.convertValue(results, Category.class));

This is all fine, and works like expected. However, the input JSON occasionally contains the boolean value of false instead of an actual item object. The JSON looks like something of the following:

{
    "id":1, 
    "items": [
        {
            "firstAttribute": "Test 1",
            "value": 1
        },
        {
            "firstAttribute": "Test 2",
            "value": 2
        },
        {
            "firstAttribute": "Test 3",
            "value": 3
        },
        false,
        false,
        false,
        {
            "firstAttribute": "Test 4",
            "value": 4
        },
        false,
        {
            "firstAttribute": "Test 5",
            "value": 5
        },
    ]
}

The boolean value throws off the parser, making it throw the exception of

java.lang.IllegalArgumentException: Can not instantiate value of type [simple type, class com.example.test.Category$Item] from JSON boolean value; no single-boolean/Boolean-arg constructor/factory method

I tried to solve this by using @JsonCreator

public class Category {
    public int id;
    public Collection<Item> items;
    public static class Item {
        public String firstAttribute;
        public int value;
        @JsonCreator public static Item Parse(JsonNode node) {
            if (node.isBoolean()) {
                return null;
            }

            else {
                // use default Jackson parsing, as if the method 'Parse' wasn't there
            }
        }
    }
}

And this is pretty much where I've got stuck. I haven't been able to figure out how I can call the default Jackson Deserializer, . Of course, I could simply retrieve and set the values myself, however, in the actual project I'm building this for, there is a large amount of complex models, and various, inconsistent json inputs, and I'd rather avoid parsing everything manually.


Solution

  • Unfortunately that's valid JSON, this should do the trick:

    public class Category {
        private Integer id;
        private Collection<Item> items = Lists.newArrayList();
    
        @JsonCreator
        public Category(@JsonProperty("id") Integer id, 
                        @JsonProperty("items") ArrayNode nodes) {
            this.id = id;
            for (int i = 0; i < nodes.size(); i++) {
                JsonNode node = nodes.get(i);
                if (!node.isBoolean()) {
                    items.add(objectMapper.readValue(node, Item.class));
                }
            }
        }
        ...
    }