2010-10-17 15 views
7

ich bin versucht, eine Klasse MyRootClass mit einer Eigenschaft json-Serialisierung, die eine Sammlung von Elementen einer zweiten Klasse MyClass ist:Jackson: kundenspezifische Sammlung Serialisierung JSON

public class MyRootClass { 
    private List<MyInterface> list = new ArrayList<MyInterface>(); 
    // getter/setter 
} 

public class MyClass implements MyInterface { 
    private String value = "test";  
    // getter/setter 
} 

Der folgende Code:

MyRootClass root = new MyRootClass(); 
root.getList().add(new MyClass()); 
ObjectMapper mapper = new ObjectMapper(); 
mapper.writeValue(System.out, root); 

Erzeugt diese JSON Ausgabe:

{"list": [ {"value":"test"} ] } 

statt, was ich brauche, um jeden Gegenstand in der Spalte Lektion mit einem Namen serialisiert:

{"list": [ {"myclass": {"value":"test"}} ] } 

Gibt es eine Möglichkeit, um es mit Jackson zu erreichen? Ich habe darüber nachgedacht, einen benutzerdefinierten Serializer zu schreiben, aber ich habe nichts gefunden, was mit einer Sammlung von Objekten zu tun hat.

Antwort

7

Es hängt davon ab, was genau Sie mit Namen erreichen möchten; aber ja, das kann gemacht werden, wenn du 'myclass' hier eingeben willst, ist type information (oder kann so tun, als ob sie benutzt wurde; wenn du Jackson nicht zur Deserialisierung benutzt, ist es nicht wirklich wichtig).

Wenn ja, würden Sie MyInterface mit Anmerkungen versehen:

@JsonTypeInfo(use=Id.NAME, include=As.WRAPPER_OBJECT) 

und MyClass mit:

@JsonTypeName("myclass") 

(wenn Sie das nicht definieren, würde Standardname nicht qualifizierte Namen der Klasse sein)

@JsonTypeInfo oben definiert, dass der Typname verwendet werden soll (anstelle des Java-Klassennamens oder der benutzerdefinierten Methode), und die Einbindung erfolgt mithilfe eines Wrapper-Objekts (Alternativen sind Wrapper) Array und As-Eigenschaft)

Sie sollten dann erwartet Ausgabe sehen.

1

Sie möchten den Namen der Klasse in die Ausgabe aufnehmen. Dies ist nicht der Fall, wenn sich json serializer verhält - sie enthalten nur Feldnamen.

Was Sie tun können, ist eine andere Klasse einzuführen.

class MyClass implements MyInterface { 
    private MyOtherClass myclass; 
} 

class MyOtherClass { 
    private String value = "test"; 
} 
+0

Danke. Das habe ich versucht zu vermeiden, weil ich ein Legacy-Klassenmodell verwende (ich kann es nicht ändern), aber ich muss das JSON-Format erhalten (auch eine Einschränkung, die von einem Drittsystem auferlegt wird). –

+1

Sie können das Legacy-Klassenmodell zum Zweck der Serialisierung umbrechen. – Bozho

1

Sie können ein Hilfsobjekt wie folgt verwenden:

public static class MyObject { 
    public int i; 
    public MyObject(int i) { this.i = i; } 
    public MyObject() {} 
} 

@JsonDeserialize(contentAs=MyObject.class) 
public static class MyHelperClass extends ArrayList<MyObject> { 

} 

@Test 
public void testCollection() throws JsonGenerationException, JsonMappingException, IOException { 
    final Collection<MyObject> l = new ArrayList<MyObject>(); 
    l.add(new MyObject(1)); 
    l.add(new MyObject(2)); 
    l.add(new MyObject(3)); 

    final ObjectMapper mapper = new ObjectMapper(); 

    final String s = mapper.writeValueAsString(l); 
    final Collection<MyObject> back = mapper.readValue(s, MyHelperClass.class); 

} 
Verwandte Themen