2016-12-07 60 views
1

我具有由杰克逊序列化此Java模型:杰克逊序列与递归结构

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="orderId") 
public class ClonedOrder extends ResourceSupport implements Serializable{ 
    private long orderId; 
    private ClonedOrder parent; 
    private List<ClonedOrder> children = new ArrayList<>(); 

    @JsonProperty("root") 
    public ClonedOrder root() { 
     if (parent == null) { 
      return this; 
     } else { 
      return parent.root(); 
     } 
    } 

当杰克逊序列化此树的响应是如下:

{ 
    "orderId": 163811134, 
    "parent": { 
    "orderId": 153684020, 
    "parent": null, 
    "children": [], 
    "root": 153684020 
    }, 
    "children": [ 
    { 
    "orderId": 163811135, 
    "parent": 163811134, 
    "children": [], 
    "root": 153684020 
    }, 
    "root": 153684020 
} 

的问题是,根节点那是ClonedOrder类型不是序列化为一个ClonedOrder(与父,子和根),但只有与作为长类型的id。

问题是我不能使用相同的模型进行序列化和反序列化,因为json从服务器更改为客户端。

任何想法如何实现这一目标?

+1

JSON只能包含值;该格式没有任何引用对象的定义。 JSON无法处理对象引用中的表示循环。您需要根据这些约束来设计您的API和JSON模型,并相应地编写您的客户端和服务器代码。 – dsh

回答

1

正如您之前注意到的,使用JsonIdentityInfo jackson只是串行化了long orderId,它跳过了标准java对象序列化以避免无限嵌套对象(意味着stackoverflow)。

我建议使用一个更简单的数据结构来串行化所有需要的数据,比如将这些数据存储在关系数据库中的模型。我搞清楚这个模型是这样的:

relations: [ 
    {"id": 163811134, "parent": 153684020}, 
    {"id": 163811135, "parent": 163811134}, 
    {"id": 153684020, "parent": null}, 
] 

这种结构是很简单的找到你需要的东西使用的实用方法:

private class CloningRelations { 
    List<CloningOrder> orders; 

    public Long getRoot(){ 
     for (CloningOrder o : orders) 
      if (o.getParent() != null) 
       return o.getId(); 
     return null; 
    } 

    @JsonIgnore public List<Long> getChildrenOf(long id) { 
     ArrayList<Long> list = new ArrayList<>(); 
     for (CloningOrder o : orders) 
      if (o.getParent() == id) 
       list.add(o.getId()); 
     return list; 
    } 

    @JsonIgnore public List<Long> getDescendantsOf(long id) { 
     ArrayList<Long> list = new ArrayList<>(); 
     for (CloningOrder o : orders) 
      if (o.getParent() == id) { 
       list.add(o.getId()); 
       list.addAll(getDescendantsOf(o.getId())); 
      } 
     return list; 
    } 

    @JsonIgnore public Long getParentOf(long id) { 
     for (CloningOrder o : orders) 
      if (o.getId() == id) 
       return o.getParent(); 
     return null; 
    } 

    @JsonIgnore public List<Long> getAncestorsOf(long id) { 
     ArrayList<Long> list = new ArrayList<>(); 
     for (CloningOrder o : orders) 
      if (o.getId() == id) { 
       list.add(o.getParent()); //sorted too! 
       list.addAll(getAncestorsOf(o.getParent())); 
      } 
     return list; 
    } 

    private class CloningOrder { 
     long id; 
     Long parent; 

     public long getId() { 
      return id; 
     } 

     public void setId(long id) { 
      this.id = id; 
     } 

     public Long getParent() { 
      return parent; 
     } 

     public void setParent(Long parent) { 
      this.parent = parent; 
     } 

    } 
} 
0

您可以使用两个注解@JsonManagedReference@JsonBackReference处理双向参考。

看一看here