javajsonjacksonjsonnode

What is the cleanest way to unwrap nested JSON values with Jackson in Java?


I have a JSON which looks like this (number of fields heavily reduced for the sake of example):

{
  "content": {
    "id": {"content": "1"},
    "param1": {"content": "A"},
    "param2": {"content": "55"}
  }
}

Keep in mind, that I don't have control over it, I can't change it, that is what I get from API.

I've created a POJO class for this looking like that:

public class PojoClass {
  private String id;
  private String param1;
  private String param2;

  // getters and setters
}

Then I parse JSON with Jackson (I have to use it, please don't suggest GSON or else):

ObjectMapper om = new ObjectMapper();
JsonNode jsonNode = om.readTree(json).get("content");
PojoClass table = om.readValue(jsonNode.toString(), PojoClass.class);

And this doesn't work, because of id, param1 and param2 having JSON in them, not straight values. The code works fine with JSON like this:

{
  "content": {
    "id": "1",
    "param1": "A",
    "param2": "55"
  }
}

But unfortunately the values I need are stored under "content" fields.

What is the cleanest way to resolve this?

I understand that I can hardcode this and extract all values into variables one by one in constructor or something, but there are a lot of them, not just 3 like in this example and obviously this is not the correct way to do it.


Solution

  • You can modify the JsonNode elements like "id": {"content": "1"} to {"id": "1"} inside your json string accessing them as ObjectNode elements with an iterator and after deserialize the new json obtained {"id":"1","param1":"A","param2":"55"} like below:

    String content = "content";
    ObjectMapper om = new ObjectMapper();
    JsonNode root = om.readTree(json).get(content);
    
    Iterator<String> it = root.fieldNames();
    while (it.hasNext()) {
        String fieldName = it.next();
        ((ObjectNode)root).set(fieldName, root.get(fieldName).get(content));
    } 
    
    PojoClass table = om.readValue(root.toString(), PojoClass.class);
    System.out.println(table); //it will print PojoClass{id=1, param1=A, param2=55}