2010-10-17 33 views
7

sto cercando di JSON-serializzare un MyRootClass classe con una proprietà che è una raccolta di elementi di secondo classe MyClass:Jackson: custom collection serializzazione JSON

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

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

Il seguente codice:

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

genera questo uscita JSON:

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

invece di quello che mi serve, ogni oggetto nella col lection serializzato con un nome:

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

Esiste un modo per realizzarlo con Jackson? Ho pensato di scrivere un serializzatore personalizzato, ma non ho trovato nulla relativo a una collezione di oggetti.

risposta

7

Dipende da cosa esattamente si desidera ottenere con il nome; ma sì, questo può essere fatto se si desidera includere "myclass" qui è di tipo information (o può agire come se fosse usato, se non si usa Jackson per deserializzare non ha molta importanza).

Se è così, si dovrebbe annotare MyInterface:

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

e MyClass con:

@JsonTypeName("myclass") 

(se non si definisce che, nome di default sarebbe nome non qualificato della classe)

@JsonTypeInfo in alto definisce il nome di tipo da utilizzare (anziché il nome classe Java o il metodo personalizzato) e l'inclusione viene eseguita utilizzando un oggetto wrapper (le alternative sono wrapper array e come proprietà)

Quindi dovresti vedere l'output previsto.

1

Quello che vuoi è includere il nome della classe nell'output. Questo non è il modo in cui si comportano i serializzatori json: includono solo i nomi dei campi.

Quello che puoi fare è introdurre un'altra classe.

class MyClass implements MyInterface { 
    private MyOtherClass myclass; 
} 

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

Grazie. Questo è quello che stavo cercando di evitare, perché sto usando un modello di classe legacy (non posso modificarlo), ma ho bisogno di ottenere quel formato JSON (anche una restrizione imposta da un sistema di terze parti). –

+1

è possibile eseguire il wrap del modello di classe legacy ai fini della serializzazione. – Bozho

1

È possibile utilizzare un oggetto helper come questo:

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

} 
Problemi correlati