【问题标题】:Jackson: @JsonIdentityInfo Object instead of id杰克逊:@JsonIdentityInfo 对象而不是 id
【发布时间】:2016-01-02 17:15:19
【问题描述】:

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

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

因此,Jackson 不应引用 id 为 1 的“otherObj”,而应包含整个对象。

{
    "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)。

【问题讨论】:

  • github.com/FasterXML/jackson-databind/issues/372@JsonIdentityInfo isn't meant to do that: it's meant to resolve cyclic dependencies in an object graph (during serialization and deserialization) by using an ID/reference mechanism so that an object instance is only completely serialized once and referenced by its ID elsewhere. So your first point ("making incomplete JSON objects") is an intended behaviour.
  • 那么,使用双向引用(因此 JsonManagedReference/JsonBackReference 不起作用)以及序列化和反序列化(我找不到让 JsonView 使用反序列化的方法)的最佳解决方案是什么。实体模型相当复杂,所以 JsonIgnore 不是解决方案。
  • 抱歉,我没有用过 Jackson...我只是指出一些似乎相关的东西

标签: java json jackson jsonidentityinfo


【解决方案1】:

就像在 cmets 和链接中所说的那样,@JsonIdentityInfo 和 Jackson 生成器似乎没有启用插入对象而不是 id 的选项。

经过更多研究,我们终于发现了这一点: deserialize Jackson object in JavaScript containing JsonIdentityInfo

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

【讨论】:

    【解决方案2】:

    问题恰恰在于 Jackson 如何将 java 对象序列化为 JSON。 当我们使用@JsonIdentityInfo 解决对象图中的循环依赖问题时,我们正在强制序列化机制将JSON 中Java 对象的第一次出现序列化,并将随后的出现替换为生成的id。

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

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

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

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

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

    【讨论】:

      【解决方案3】:

      This 是我找到的最佳解决方案。 通过@JsonIdentityInfo 清理循环引用以及现在公开的解决方案,我没有循环引用,杰克逊返回整个值数组

      【讨论】:

      • 最好 - 至少 - 在你的答案中总结链接的文章,以防链接失效。
      猜你喜欢
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      • 2013-10-05
      • 1970-01-01
      • 2022-06-22
      • 2018-09-25
      • 2017-08-04
      相关资源
      最近更新 更多