2016-05-18 23 views
4

Ich versuche, die @JsonIdentityInfo von Jackson 2 wie beschrieben here zu verwenden.Wie @JsonIdentityInfo mit Zirkelverweisen verwenden?

Zu Testzwecken habe ich die folgenden zwei Klassen:

public class A 
{ 
    private B b; 
    // constructor(s) and getter/setter omitted 
} 
public class B 
{ 
    private A a; 
    // see above 
} 

Natürlich die naive Ansatz failes:

@Test 
public void testJacksonJr() throws Exception 
{ 
    A a = new A(); 
    B b = new B(a); 
    a.setB(b); 
    String s = JSON.std.asString(a);// throws StackOverflowError 
    Assert.assertEquals("{\"@id\":1,\"b\":{\"@id\":2,\"a\":1}}", s); 
} 

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") der Klasse A und/oder Klasse B entweder nicht funktioniert Hinzufügen .

Ich hatte gehofft, dass ich (und später deserialize) a zu so etwas wie dieses serialisieren könnte: (nicht ganz sicher über die JSON obwohl)

{ 
    "b": { 
     "@id": 1, 
     "a": { 
      "@id": 2, 
      "b": 1 
     } 
    } 
} 

Wie kann ich das tun?

+0

Das funktioniert gut für mich und erzeugt '{" @id ": 1," b ": {" @ id ": 2," a ": 1}}'. –

+0

Seltsam. Ich benutze jackson-jr-all-2.7.4.jar und com.fasterxml.jackson.jr.ob.JSON. Welche JSON-Klasse hast du benutzt? Mit der Anmerkung zu beiden Klassen? – Burkhard

+0

Ich habe gerade einen 'ObjectMapper' erstellt und' writeValueAsString' verwendet. (Dies ist mit Ihren @ JsonIdentityInfo Annotationen.) –

Antwort

7

Es scheint jackson-jr hat eine Teilmenge von Jackson-Features. @JsonIdentityInfo darf den Schnitt nicht gemacht haben.

Wenn Sie die vollständige Jackson-Bibliothek verwenden können, verwenden Sie einfach einen Standard ObjectMapper mit der @JsonIdentityInfo Annotation, die Sie in Ihrer Frage vorgeschlagen haben, und serialisieren Sie Ihr Objekt. Zum Beispiel

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 
public class A {/* all that good stuff */} 

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 
public class B {/* all that good stuff */} 

und dann

A a = new A(); 
B b = new B(a); 
a.setB(b); 
ObjectMapper mapper = new ObjectMapper(); 
System.out.println(mapper.writeValueAsString(a)); 

werden

{ 
    "@id": 1, 
    "b": { 
     "@id": 2, 
     "a": 1 
    } 
} 

erzeugen, wo die verschachtelten a durch seine @id auf das Wurzelobjekt beziehen.

+0

@ Sotirios Delimanolis Eine Idee, wie Sie die "@id" in der JSON-Antwort zu ignorieren? – SuRa

+1

@SuRa Was meinst du mit _ignore_? Das ist der Punkt von '@ JsonIdentityInfo', um eine Eigenschaft (die einen beliebigen Namen haben kann) bereitzustellen, die das Objekt identifiziert. –

+0

Beim Abrufen von Daten aus dem Rest-Client erhalte ich << com.fasterxml.jackson.databind.JsonMappingException: Kann den Wert des Typs [einfacher Typ, Klassenname] nicht von Integral Nummer (1) instanziieren; Keine single-int-arg Konstruktor/Factory-Methode >> Ausnahme. Wie behebe ich das? Das verschachtelte "a": 1 verursacht das Problem. – SuRa

0

In einigen Fällen kann es notwendig sein, den Id Property mit @JsonProperty ("id")

Zum Beispiel in meinem Fall mit Anmerkungen versehen, machte dies meine Anwendung ordnungsgemäß ausgeführt.

+0

Das ist schon ein Teil der akzeptierten Antwort. Gibt es noch etwas oder Neues, das Sie dieser Antwort hinzufügen möchten? –