user320550
user320550

Reputation: 1185

Deserialize json into complex Map object using jackson

Consider the following json example

{
    "key1" : {

        "k11":["vala","valb","valc"],
        "k12":["vald"],
        "k13":["vale","valf"]
    },
    "key2" : {

        "key21":["valg","valh","vali"],
        "key22":["valj"],
        "key23":["valk","vall"]
    }
}

This translates into a Map<String,Map<String,List<String>>>.

Could anyone please let me know how i can convert this in this into this complex Map object. I do a a method called constructMapType, but not sure if it handles complex Map type.

Upvotes: 1

Views: 1509

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 209092

Seems to work fine with .constructMapType(Map.class, String.class, Map.class)

public static void main(String[] args) throws Exception {
    final String json
            = "{\n"
            + "    \"key1\" : {\n"
            + "        \"k11\":[\"vala\",\"valb\",\"valc\"],\n"
            + "        \"k12\":[\"vald\"],\n"
            + "        \"k13\":[\"vale\",\"valf\"]\n"
            + "    },\n"
            + "    \"key2\" : {\n"
            + "        \"key21\":[\"valg\",\"valh\",\"vali\"],\n"
            + "        \"key22\":[\"valj\"],\n"
            + "        \"key23\":[\"valk\",\"vall\"]\n"
            + "    }\n"
            + "}";
    ObjectMapper mapper = new ObjectMapper();

    Map<String, Map<String, List<String>>> map 
            = mapper.readValue(json,TypeFactory.defaultInstance()
                    .constructMapType(Map.class, String.class, Map.class));

    for (String outerKey: map.keySet()) {
        System.out.println(outerKey + ": " + map.get(outerKey));
        for (String innerKey: map.get(outerKey).keySet()) {
            System.out.print(innerKey + ": [");
            for (String listValue: map.get(outerKey).get(innerKey)) {
                System.out.print(listValue + ",");
            }
            System.out.println("]");
        }
    }
}

You could go all the way down listing all the generics down to the List<String>, but as seen above it isn't necessary. But just to show what I mean

TypeFactory factory = TypeFactory.defaultInstance();
Map<String, Map<String, List<String>>> map 
        = mapper.readValue(json, factory.constructMapType(
                Map.class, 
                factory.constructType(String.class), 
                factory.constructMapType(
                        Map.class, 
                        factory.constructType(String.class), 
                        factory.constructCollectionType(
                                List.class, 
                                String.class))));

Upvotes: 2

Related Questions