我有这个由杰克逊序列化的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作为long类型。
问题是我不能使用相同的模型进行序列化和反序列化,因为json从服务器更改为客户端。
知道如何实现这一目标吗?
答案 0 :(得分:1)
正如您之前注意到的那样,使用JsonIdentityInfo
jackson只是序列化long orderId
并跳过标准的java对象序列化以避免无限的嵌套对象(意味着堆栈溢出)。
我建议使用更简单的数据结构序列化所需的所有数据,例如用于将这些数据存储在关系数据库中的模型。我弄清楚的模型是:
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;
}
}
}
答案 1 :(得分:1)
您可以使用两个注释@JsonManagedReference
和@JsonBackReference
来处理双向引用。
看看here