2016-12-07 93 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