Java – jackson starts deserializing two levels

jackson starts deserializing two levels… here is a solution to the problem.

jackson starts deserializing two levels

I have a clumsy json file with a clumsy construction like this:

{
"clientByClientId" : {
  "123" : {
    "clientId" : "123"
     "moreFields" : "moreData"
   }
  "456" : {
    "clientId" : "456"
     "moreFields" : "moreData"
   }
 }
}

As you can see, the first two layers of this JSON are redundant. What is the best way to deserialize it into a collection of Client objects? I tried using the online json to pojo tools, but they ended up generating classes named “123” and “456”. Ideally, I’d like to use Jackson but be open to other solutions.

Solution

Tip: Your JSON is malformed because it is missing several commas. Once you add these, this will be useful to you.

First, you need a class to represent Client:

public class Client {
    private final int clientId;
    private final String moreFields;

@JsonCreator
    public Client(@JsonProperty("clientId") int clientId, 
                  @JsonProperty("moreFields") String moreFields) {
        this.clientId = clientId;
        this.moreFields = moreFields;
    }

@Override
    public String toString() {
        return "Client[clientId=" + clientId + ", moreFields=" + moreFields + "]";
    }
}

Now you can simply create an ObjectMapper and iterate through the elements mapped by clientByClientId, which can be done in the following way:

ObjectMapper objectMapper = new ObjectMapper();
JsonNode node = objectMapper.readTree(json).get("clientByClientId");
Map<Integer, Client> clientMap = objectMapper.readValue(node.traverse(),
        new TypeReference<Map<Integer, Client>>() {});
System.out.println(clientMap.values());

The output of this code is:

[Client[clientId=123, moreFields=moreData], Client[clientId=456, moreFields=moreData]]

Related Problems and Solutions