Json Deserializer – How to get data from parent JSON object Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Json Deserializer – How to get data from parent JSON object without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I am using Spring MVC and spring take care of converting json to Objects in controller. But my json structure is different then class structure. So I have written my own deserializer. But I am getting problem to accessing values of parent object in JSON. I think it is better to explain my problem using some example –

I have following JSON to deserialize

{
  id: 1,
  children: {
    "name1": "value1",
    "name2": "value2"
  }
}

I have following classes (Sample Code) –

public class Parent {
    private Integer id;

    @JsonDeserialize(using= ChildrenDeserializer.class)
    private List<Child> children;
    //... Getter/setters
}

public class Child {
    private Integer id;
    private String name;
    private String value;

    //...getters/setters
}

public class ChildrenDeserializer extends JsonDeserializer<List<Child>> {
    @Override
    public List<Child> deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        List<Child> children = new ArrayList<>();

        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);
        Iterator<Map.Entry<String, JsonNode>> fieldsIterator = node.fields();

        while (fieldsIterator.hasNext()) {
            Map.Entry<String, JsonNode> field = fieldsIterator.next();
            String name = field.getKey();
            String value = field.getValue().textValue();

            Child child = new Child();

            //Here I want to get parentId from the Json. Is it possible??
            Integer childId = childRepository.searchChildIdByParentId(parentId, name);

            child.setId(childId);
            child.setName(name);
            child.setValue(value);
            children.add(child);
        }

        return children;
    }
}

Is there any way to get parentId (which is 1 in above example) while deserializing children??

Answer

Having the same need , I come across with your question . My solution to the problem is on the parent constructor: When create the parent class, set the correct property in the child class.

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.testng.Assert;
import org.testng.annotations.Test;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

public class JsonUnitTest {

   private static final Logger logger = LogManager.getLogger(JsonUnitTest.class);

   @Test
   public void unit() {

      // test objects
      final int parentId = 1;
      final int childId = 2;
      final ParentClass parent = new ParentClass(parentId);
      final ChildClass child = new ChildClass(childId);
      parent.setChild(child);
      
      // serialize
      final String json = JsonHelper.toJson(parent);
      logger.info(json);
      logger.info(parent);
      
      // deserialize
      final ParentClass newParent = JsonHelper.fromJson(json, ParentClass.class);

      // asserts
      Assert.assertNotNull(newParent);
      Assert.assertEquals(newParent, parent);

   }

The result of the test is

[main] INFO JsonUnitTest:29 {"id":1,"child":{"childId":2}}
[main] INFO JsonUnitTest:30 ParentClass [id=1, child=ChildClass [parentId=1, childId=2]]
PASSED: unit

Here the rest of the code :

   public static class ParentClass {
      
      public static final String idKey = "id";
      public static final String childKey = "child";
      
      @JsonProperty(idKey)
      private int id;
      
      @JsonProperty(childKey)
      private ChildClass child;
      
      public ParentClass(int id) {
         this.id = id;
      }

      @JsonCreator
      public ParentClass(
            @JsonProperty(idKey) int id, 
            @JsonProperty(childKey) ChildClass child) {
         super();
         this.id = id;
         setChild(child);
      }

      @JsonProperty(idKey)
      public int getId() {
         return id;
      }

      @JsonProperty(idKey)
      public void setId(int id) {
         this.id = id;
      }

      @JsonProperty(childKey)
      public ChildClass getChild() {
         return child;
      }
      
      @JsonProperty(childKey)
      public void setChild(ChildClass child) {
         this.child = child;
         child.setParentId(id);
      }

      @Override
      public int hashCode() {
         final int prime = 31;
         int result = 1;
         result = prime * result + ((child == null) ? 0 : child.hashCode());
         result = prime * result + id;
         return result;
      }

      @Override
      public boolean equals(Object obj) {
         if (this == obj)
            return true;
         if (obj == null)
            return false;
         if (getClass() != obj.getClass())
            return false;
         ParentClass other = (ParentClass) obj;
         if (child == null) {
            if (other.child != null)
               return false;
         } else if (!child.equals(other.child))
            return false;
         if (id != other.id)
            return false;
         return true;
      }

      @Override
      public String toString() {
         return "ParentClass [id=" + id + ", child=" + child + "]";
      }
   }
   
   public static class ChildClass {
      
      public static final String parentIdKey = "../" + ParentClass.idKey;
      public static final String childIdKey = "childId";
      
      private int parentId;
      private int childId;
      
      @JsonCreator
      public ChildClass(@JsonProperty(childIdKey) int childId) {
         super();
         this.childId = childId;
      }

      @JsonIgnore
      public int getParentId() {
         return parentId;
      }

      @JsonProperty(parentIdKey)
      public void setParentId(int parentId) {
         this.parentId = parentId;
      }

      @JsonProperty(childIdKey) 
      public int getChildId() {
         return childId;
      }

      @JsonProperty(childIdKey) 
      public void setChildId(int childId) {
         this.childId = childId;
      }

      @Override
      public int hashCode() {
         final int prime = 31;
         int result = 1;
         result = prime * result + childId;
         result = prime * result + parentId;
         return result;
      }

      @Override
      public boolean equals(Object obj) {
         if (this == obj)
            return true;
         if (obj == null)
            return false;
         if (getClass() != obj.getClass())
            return false;
         ChildClass other = (ChildClass) obj;
         if (childId != other.childId)
            return false;
         if (parentId != other.parentId)
            return false;
         return true;
      }

      @Override
      public String toString() {
         return "ChildClass [parentId=" + parentId + ", childId=" + childId + "]";
      }
   }
}
We are here to answer your question about Json Deserializer – How to get data from parent JSON object - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji