2010-10-17 14 views
7

Estoy tratando de JSON-serializar un MyRootClass clase con una propiedad que es una colección de elementos de una segunda clase MyClass:Jackson: Colección de la aduana de serialización de JSON

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

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

El siguiente código:

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

Genera esta salida JSON:

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

en lugar de lo que necesito, cada objeto en el col lection serializado con un nombre:

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

¿Hay alguna forma de lograrlo con Jackson? Pensé en escribir un serializador personalizado, pero no encontré nada relacionado con una colección de objetos.

Respuesta

7

Depende de qué exactamente quiere lograr con el nombre; pero sí, esto se puede hacer si desea incluir 'myclass' aquí, escriba información (o puede actuar como si se hubiera usado, si no usa Jackson para deserializar, realmente no importa).

Si es así, sería anotar MyInterface:

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

y MiClase con:

@JsonTypeName("myclass") 

(si no se define que, nombre por defecto sería nombre no calificado de la clase)

@JsonTypeInfo anterior define que se debe usar el nombre de tipo (en lugar del nombre de clase de Java o el método personalizado), y la inclusión se realiza mediante el uso de un objeto contenedora (las alternativas son envoltorio array y como-propiedad)

Entonces debería ver la salida esperada.

1

Lo que desea es incluir el nombre de la clase en el resultado. No es así como se comportan los serializadores json, sino que solo incluyen nombres de campo.

Lo que puedes hacer es introducir otra clase.

class MyClass implements MyInterface { 
    private MyOtherClass myclass; 
} 

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

Gracias. Eso es lo que estaba intentando evitar, porque estoy usando un modelo de clase heredado (no puedo modificarlo), pero necesito obtener ese formato JSON (también una restricción impuesta por un sistema de terceros). –

+1

puede envolver el modelo de clase heredado para fines de serialización. – Bozho

1

Se puede utilizar un objeto auxiliar de la siguiente manera:

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

} 
Cuestiones relacionadas