我有两个对象之间的双向关系。我有一个使用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>
答案 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。