【问题标题】:Json Deserializer - How to get data from parent JSON objectJson Deserializer - 如何从父 JSON 对象获取数据
【发布时间】:2014-10-11 10:32:44
【问题描述】:

我正在使用 Spring MVC,并且 spring 负责将 json 转换为控制器中的对象。但我的 json 结构与类结构不同。所以我写了自己的反序列化器。但是我在访问 JSON 中的父对象的值时遇到了问题。我认为最好用一些例子来解释我的问题 -

我有以下 JSON 来反序列化

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

我有以下课程(示例代码) -

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;
    }
}

有没有办法在反序列化子代时获取 parentId(上例中为 1)??

【问题讨论】:

  • 既然你正在编写整个反序列化器,为什么不跳过自动的东西并反序列化父级。然后您可以将id(或父级)传递给您的子反序列化方法。
  • 感谢您的回复。我现在已经这样做了,并且工作正常。但仍然想知道是否有任何方法可以使用父对象的默认反序列化器获取父对象。因为父级中有很多属性,默认的反序列化器在那里可以正常工作。

标签: java spring jackson json-deserialization


【解决方案1】:

有同样的需求,我遇到了你的问题。我的解决方法是在父构造函数上:创建父类时,在子类中设置正确的属性。

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);

   }

测试结果是

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

剩下的代码在这里:

   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 + "]";
      }
   }
}

【讨论】:

    猜你喜欢
    • 2012-07-13
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2018-10-12
    相关资源
    最近更新 更多