无法获取@JsonIdentityInfo注释

时间:2013-03-14 12:35:56

标签: json rest java-ee jackson

我有两个对象之间的双向关系。我有一个使用Jersey 1.17和Jackson 2.1.4的RESTful Web服务。我也在使用@JsonIdentityInfo注释(显然是错误的方式!)来阻止Json进入无限循环。但是,生成的Json仍然是两个对象之间的无限循环。

第一个对象是:

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

    private long value;
    private Parent parent;

    public long getValue() {
        return this.value;
    }

    public void setValue(long value) {
        this.value = value;
    }

    public Parent getParent() {
        return this.parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }

}

第二个对象是:

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

    private long value;
    private Set<Child> childs = new HashSet<Child>(0);

    public long getValue() {
        return this.value;
    }

    public void setValue(long value) {
        this.value = value;
    }

    public Set<Child> getChilds() {
        return this.childs;
    }

    public void setChilds(Set<Child> childs) {
        this.childs = childs;
    }

}

这是生成Json的方法。

@GET
@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
public Child getChild() {

    Child child = new Child();
    Parent parent = new Parent();
    child.setValue(1L);
    parent.setValue(2L);
    child.setParent(parent);
    Set<Child> childs = new HashSet<Child>(0);
    childs.add(child);
    parent.setChilds(childs);
    return child;

}

修改

结果Json看起来像这样:

{"value":1,"parent":{"value":2,"childs":[{"value":1,"parent":{"value":2,"childs":[...

这些9行在服务器的日志文件中一遍又一遍地重复......

at org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
at org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:72)
at org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)

web.xml文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  id="WebApp_ID" version="2.5">
  <display-name>Jersey REST Service</display-name>
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>test</param-value>      
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/api/*</url-pattern>
  </servlet-mapping>
 </web-app> 

2 个答案:

答案 0 :(得分:5)

你说你正在使用Jackson 2.1.4但是堆栈跟踪显示Jackson的包装以“org.codehaus.jackson”开头,这是Jackson 1.x的基础包。 Jackson 2.x的基础包是“com.fasterxml.jackson”。因此,泽西岛配置了Jackson 1.x(最可能是1.9.2,因为the default in Jersey 1.17)。我的猜测是你使用从Jackson 2.x导入的Annotations来注释你的代码,但Jersey使用的Jackson库并没有意识到这些,所以无法序列化。

您的代码适用于Jackson 2.3.0。

答案 1 :(得分:3)

对于字段之间的双向链接,您应该查看@JsonManagedReference@JsonBackReference注释。 我认为根本不能用@JsonIdentifyInfo达到这种行为。

public class Parent {

private long value;
@JsonManagedReference private Set<Child> childs = new HashSet<Child>(0);

public long getValue() {
    return this.value;
}

public void setValue(long value) {
    this.value = value;
}

public Set<Child> getChilds() {
    return this.childs;
}

public void setChilds(Set<Child> childs) {
    this.childs = childs;
}

}

...

public class Child {

private long value;
@JsonBackReference private Parent parent;

public long getValue() {
    return this.value;
}

public void setValue(long value) {
    this.value = value;
}

public Parent getParent() {
    return this.parent;
}

public void setParent(Parent parent) {
    this.parent = parent;
}

}

您可以找到更多示例here