杰克逊:@JsonIdentityInfo对象而不是id

时间:2016-01-02 17:15:20

标签: java json jackson jsonidentityinfo

有没有办法用@JsonIdentityInfo影响序列化过程,以便它插入整个对象而不是引用id?

@Entity
@JsonIdentityInfo(
        generator = ObjectIdGenerators.IntSequenceGenerator.class,
        property = "linkLabel")
public class LinkLabel implements Serializable {
   //...
}

所以不要引用" otherObj"如果身份证1,杰克逊应该包括整个对象。

{
    "objects": [{
            "id": 1,
            "otherObj": [{
                    "id": 1,
                    ...
                }, {
                    "id": 3,
                    ...
                }]
        },
            "id": 2,
            "otherObj": [1] <-- referencing otherObj with id 1
    ]
}

喜欢这里:

{
    "objects": [{
            "id": 1,
            "otherObj": [{
                    "id": 1,
                    ...
                }, {
                    "id": 3,
                    ...
                }]
        },
            "id": 2,
            "otherObj": [{
                    "id": 1,  <-- desired format, whole object
                    ...
                }]
    ]
}

我们有双向引用,因此@JsonManagedReference和@JsonBackReference无法正常工作。此处描述了此行为(http://wiki.fasterxml.com/JacksonFeatureObjectIdentity)。

3 个答案:

答案 0 :(得分:2)

如评论和链接中所述,@ JsonIdentityInfo和Jackson Generators似乎没有选项来启用插入对象而不是ID。

经过更多的研究,我们终于找到了这个: deserialize Jackson object in JavaScript containing JsonIdentityInfo

这正是我们所拥有的场景,我们现在正在使用JSOG,它针对双向引用进行了优化,它就像服务器和客户端(AngularJS)端的魅力一样。

答案 1 :(得分:0)

问题正是杰克逊如何将java对象序列化为JSON。 当我们使用@JsonIdentityInfo来解决对象图中的循环依赖问题时,我们强制序列化机制将JSON中第一次出现的Java对象序列化,然后将后续出现的事件替换为生成的id。

何时为Java对象创建JSON的决定因素是基于对创建JAVA对象的内存位置的访问。

因此,欺骗序列化机制的一个好方法是创建子对象的副本然后设置它。这样,属于集合中不同父级的相同子对象将被视为不同的子对象实例。

创建对象的精确副本的一个好方法是使用SerializationUtils.serialize / desrialize方法。

    byte[] bs= SerializationUtils.serialize(classObject);
    ClassObject cloneEntity = (ClassObject ) SerializationUtils.deserialize(bs);

这会在不同的内存重定位中创建一个对象的精确副本。

答案 2 :(得分:0)

This是我发现的最佳解决方案。 通过@JsonIdentityInfo清除循环引用和现在公开的解决方案后,我没有循环引用,杰克逊返回了整个值数组