Question

I have an immutable JSON with a structure like

{
  "data": "mydata",
  "information": [
    {
      "info": "mnkjshdflkj",
      "stuff": "things"
    },
    {
      "info": "khsjfdaksdfh",
      "stuff": "more things"
    }
  ]
}

and I am using Jackson to deserialize. What I am trying to achieve is to store this information in a POJO under this format.

MyData.java

public class MyData {
     String data;
     HashMap<String, Info> information; 
}

Info

public class Info {
     String info; // is it required?
     String stuff;
}

My map keys would be the values in the info field and the values would be the class itself. What would be the jackson approach to this process?

Was it helpful?

Solution

If I understand you correctly, this should work. At first create custom deserializer for information field.

public class CustomDeserializer extends JsonDeserializer<Map<String, Info>> {
    @Override
    public Map<String, Info> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        List<Info> raw = jp.readValueAs(new TypeReference<List<Info>>() {
        });
        Map<String, Info> result = new HashMap<>();
        for (Info info : raw) {
            result.put(info.getInfo(), info);
        }

        return result;
    }
}

Then you need to register this deserializer. You can do it with help of annotation on the information field. Or register deserializer in a different way.

@JsonDeserialize(using = CustomDeserializer.class)
    Map<String, Info> information;

And full code to test:

import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.type.TypeReference;

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

public class Main {
public static void main(String[] args) throws IOException {
    String json = "{\n" +
            "  \"data\": \"mydata\",\n" +
            "  \"information\": [\n" +
            "    {\n" +
            "      \"info\": \"mnkjshdflkj\",\n" +
            "      \"stuff\": \"things\"\n" +
            "    },\n" +
            "    {\n" +
            "      \"info\": \"khsjfdaksdfh\",\n" +
            "      \"stuff\": \"more things\"\n" +
            "    }\n" +
            "  ]\n" +
            "}";

    ObjectMapper mapper = new ObjectMapper();
    MyData data = mapper.readValue(json, MyData.class);
    System.out.println(data);
}

public static class MyData {
    String data;
    @JsonDeserialize(using = CustomDeserializer.class)
    Map<String, Info> information;

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Map<String, Info> getInformation() {
        return information;
    }

    public void setInformation(Map<String, Info> information) {
        this.information = information;
    }

    @Override
    public String toString() {
        return "MyData{" +
                "data='" + data + '\'' +
                ", information=" + information +
                '}';
    }
}

public static class Info {
    String info; // is it required?
    String stuff;

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public String getStuff() {
        return stuff;
    }

    public void setStuff(String stuff) {
        this.stuff = stuff;
    }

    @Override
    public String toString() {
        return "Info{" +
                "info='" + info + '\'' +
                ", stuff='" + stuff + '\'' +
                '}';
    }
}

public static class CustomDeserializer extends JsonDeserializer<Map<String, Info>> {
    @Override
    public Map<String, Info> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        List<Info> raw = jp.readValueAs(new TypeReference<List<Info>>() {
        });
        Map<String, Info> result = new HashMap<>();
        for (Info info : raw) {
            result.put(info.getInfo(), info);
        }

        return result;
    }
   }
 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top