11

我通过 MappingJacksonHttpMessageConverter 使用带有 Hibernate/Spring MVC 的 jackson 1.9.2。

Jackson 无法序列化双向的一对多关系,造成无限循环。

我正在使用的课程是:

  • 具有一组 SMS 实例的对话。

  • 每个 SMS 实例都有一组电话号码

  • 每个 PhoneNumber 都有一个父联系人(这是双向多对一关系)

我想要做的是序列化对话。

如果我不使用@JsonManagedReference@JsonBackReference ,那么jackson 将由于无限循环而崩溃。但是当我使用它们时,联系人不会被序列化为PhoneNumber

班级联系{
  @JsonManagedReference
  List<PhoneNumber> phoneNumber ;
}
类电话号码 {
  @JsonBackReference
  联系方式;
}

输出是:

{ <--------------------- 对话
    “身份证”:51,
    “短信集”:[
      {
        “身份证”:53,
        “起源”:0123465,
        “目的地”:“06533844XY”,
        "message": "你好世界!",
        “电话号码”: [
          {
            “身份证”:64,
            "num": "06533844XY",
            “创作日期”:1333992533000,
          }
        ],
      }
    ],
    “创作日期”:1333992534000
  }

代替

{ <--------- 对话
    “身份证”:51,
    “短信集”:[
      {
        “身份证”:53,
        “起源”:0123465,
        “目的地”:“06533844XY”,
        "message": "你好世界!",
        “电话号码”: [
          {
            “身份证”:64,
            "num": "06533844XY",
            “创作日期”:1333992533000,
            "联系人": <--------------------- 缺少的部分
             {
                “身份证”:12,
                “名称”:“塞缪尔杰克逊”,
                “primaryNumber”:“06533844XY”
             }
          }
        ],
      }
    ],
    “创作日期”:1333992534000
  }
4

4 回答 4

7

我最近遇到了一个类似的问题:Jackson - serialization of entity with birectional Relations (avoiding cycles)

所以解决方案是升级到 Jackson 2.0,并在类中添加以下注释:

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, 
                  property = "@id")
public class SomeEntityClass ...

那么问题是 Spring 不适用于 Jackson 2.0。这已通过以下方式解决:

<bean id="jacksonMessageConverter"
          class="own.implementation.of.MappingJacksonHttpMessageConverter"/>

<bean class="org.springframework.web.servlet.mvc
             .annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jacksonMessageConverter"/>
            </list>
        </property>
        <property name="requireSession" value="false"/>
    </bean>

而own.implementation.of.MappingJacksonHttpMessageConverter就是基于这个:

http://www.jarvana.com/jarvana/view/org/springframework/spring-web/3.0.0.RELEASE/spring-web-3.0.0.RELEASE-sources.jar!/org/springframework/http/converter /json/MappingJacksonHttpMessageConverter.java?format=ok

但是使用ObjectMapperJackson 2.0 中的其他 Jackson 类而不是 Jackson 1.*

于 2012-04-11T18:00:32.023 回答
2

作为第一个解决方案,我保留了这些注释并创建了另一个类:ContactWithouPhoneNumber,并将其作为字段添加到 PhoneNumber 类。

现在,在渲染之前,我将除 PhoneNumber 之外的所有字段从联系人复制到 contactWithoutPhoneNumber。输出 JSON 包含我需要的所有内容。

这就是 DTO 设计模式。

于 2012-04-11T06:30:12.987 回答
0

你的类 def 中的一件事是使用 untyped List;你应该有:

List<PhoneNumber> phoneNumber ;

因为否则杰克逊在反序列化时无法知道类型是什么;甚至在序列化时也可能导致问题(因为不确定基类型)。所以我会先解决这个问题。

但另外你的依赖可能是错误的:@JsonManagedReference必须始终是序列化的第一件事。如果不是这种情况,则不能使用这些注释。如果没有看到您尝试序列化的对象,则很难确定(POJO 定义和 JSON 似乎略有不同)。

于 2012-04-11T17:16:55.510 回答
0

您可以将@JsonIgnore 添加到字段,映射器将在序列化期间跳过它们。它的功能类似于@Transient。

它在 jackson-core-asl 中。

于 2012-09-07T04:16:29.277 回答