2

2つのオブジェクト間に双方向の関係があります。私はJersey1.17とJackson2.1.4を使用するRESTfulWebサービスを持っています。また、@ JsonIdentityInfoアノテーションを使用して(間違った方法で、明らかに!)、Jsonが無限のサイクルに入るのを防ぎます。ただし、生成されたJsonは、2つのオブジェクト間の無限ループのままです。

最初のオブジェクトは次のとおりです。

@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;
    }

}

2番目のオブジェクトは次のとおりです。

@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> 
4

2 に答える 2

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;
}

}

…</p>

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;
}

}

ここでさらに例を見つけることができます。

于 2013-03-14T13:07:10.757 に答える