2011-07-21 27 views
10

Estoy tratando de ordenar un objeto JSON en una clase contenedora que contiene un objeto genérico, así como información adicional sobre la firma del objeto.Marshaling JSON y Generics en Java con Spring MVC

public class Signable<T> { 

    private T object; 
    private String signature; 

    public class Signable() { 
     generateSignature(); 
    } 

    /* Getters and setters */ 
} 

la clase contenedora funciona bien siempre que construyo con el objeto ya creado, y es capaz de producir el json deseada

@RequestMapping(value="/test/json/return",method=RequestMethod.GET) 
public @ResponseBody Signable<Cart> getTest() 
{ 
    Cart cart = new Cart(); 
    // populate cart with OrderItems ... 
    Signable<Cart> sign = new Signable<Cart>(); 
    sign.setObject(cart); 
    return sign; 
} 

que es capaz de generar la salida esperada

{ 
    "object":{ 
     "orderItems":[ 
       { 
        "id": "****", 
        "desc": "asdlfj", 
        "price": 25.53 
       } 
     ] 
    }, 
    "signature":"s9d94f9f9gdfg67d8678g6s87d6f7g6"; 
} 

Cual es el formato que quiero. Sin embargo, cuando se trata de reunir la misma JSON generado a partir pueden firmar de nuevo en pueda firmarse, recibo el siguiente error:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to Cart 

Por alguna razón que no es capaz de determinar que "objeto" en el JSON debe correlacionarse con el tipo of Cart (simplemente se establece como LinkedHashMap), aunque está especificado en el encabezado del método.

@RequestMapping(value="/test/json/post",method=RequestMethod.POST) 
public @ResponseBody Signable<Cart> postTest(@RequestBody Signable<Cart> sign) 

¿Hay una manera de indicar explícitamente de qué tipos de objetos que desea generar desde el JSON para insertar en lugar de un genérico?

Cualquier ayuda sería muy apreciada.

Gracias.

Respuesta

9

El problema aquí es el de pasar la información de tipo adecuada, para completar la información faltante (que ocurre debido al borrado de tipo de Java).

Pero la forma más fácil es a menudo sólo de tipo sub-clase que desea, tener algo como:

class CartSignable extends Signable<Cart> { } 

y el uso que, en lugar de construir instancia genérica; y si es así, la información del tipo está correctamente incluida (ya que está almacenada en la definición de clase de CartSignable, mientras que Signable solo tiene variable de tipo!).

Jackson también puede tomar información sobre el tipo durante la serialización, pero el problema aquí es cómo Spring pasaría dicha información. Por lo tanto, generalmente es más fácil usar el estilo de subclasificación. Tenga en cuenta que también puede usar clases internas anónimas para subclasificar.

+0

Esto es lo que acabé teniendo que hacer. ¡Gracias! –

+0

Esta es, de lejos, la solución más simple – Chepech

4

que extendimos

class ListMyObject extends ArrayList<MyObject> { } 

gracias StaxMan - gran ayuda
PD: el formato JSON> [{ "id": "1", "montaña": 2}, { "id ":" 3" , "montaña": 7}]

+0

Su solución funcionó para mí: D tnx –

0

que terminó la creación de otra clase:

public class JobUpdateList extends ArrayList<JobUpdate> implements Serializable { 
    //---- Members 
    private static final long serialVersionUID = 1L; 
} 

Así en el controlador, en lugar de:

public @ResponseBody String setJobStatus(@RequestBody List<JobUpdate> jobUpdates) { 

Hice esto:

public @ResponseBody String setJobStatus(@RequestBody JobUpdateList jobUpdates) {