Jacob Clark
Jacob Clark

Reputation: 3447

Nested JSON Mapping to Jackson where key is dynamic

I am looking to map a nested JSON structure into Jackson where the object is an object of dynamic IDs.

{ 
     "id1": {
          "prop": true
     },
     "id2": {
          "prop": true
     },
     "id3": {
          "prop": true
     }
 }

I currently have the following Jackson POJO:

package com.uk.jacob.containerdroid;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;

import java.util.HashMap;
import java.util.Map;

public class Container {
    private Map<String, ContainerDetails> properties = new HashMap<>();

    public class ContainerDetails {
        private boolean prop;

        public boolean getProp() {
            return prop;
        }

        public void setProp(boolean prop) {
            this.prop = prop;
        }
    }

    @JsonAnySetter
    public void add(String key, ContainerDetails value) {
        properties.put(key, value);
    }

    @JsonAnyGetter
    public Map<String, ContainerDetails> getProperties() {
        return properties;
    }

    @Override
    public String toString() {
        return "Containers {" +
                    ", properties=" + properties.toString() +
                '}';
    }
}

Which works for data that is a static property, but not nested JSON.

I get the error:

12-23 22:32:41.628  14098-14098/? W/System.err﹕ at [Source: { "test": { "prop": true } }; line: 1, column: 13] (through reference chain: com.uk.jacob.containerdroid.models.Container["test"])

How can I manipulate the above to map properly?

Upvotes: 0

Views: 2029

Answers (1)

JB Nizet
JB Nizet

Reputation: 692211

It seems you just want a Map<String, Foo>, where Foo is defined as

public class Foo {
    private boolean prop;

    // getter, setter omitted
}

Complete working example:

import java.io.IOException;
import java.util.Map;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Foo {
    private boolean prop;

    public boolean isProp() {
        return prop;
    }

    public void setProp(boolean prop) {
        this.prop = prop;
    }

    @Override
    public String toString() {
        return "Foo{" +
            "prop=" + prop +
            '}';
    }

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        String json = "{ \n" +
            "     \"id1\": {\n" +
            "          \"prop\": true\n" +
            "     },\n" +
            "     \"id2\": {\n" +
            "          \"prop\": true\n" +
            "     },\n" +
            "     \"id3\": {\n" +
            "          \"prop\": true\n" +
            "     }\n" +
            " }";
        Map<String, Foo> map = mapper.readValue(json, new TypeReference<Map<String, Foo>>() {
        });

        System.out.println("map = " + map);
    }
}

Upvotes: 1

Related Questions