2012-01-18 16 views
6

Usando Jersey estoy definiendo un servicio como:Jackson ObjectMapper con los genéricos a POJO en lugar de LinkedHashMap

@Path("/studentIds") 
public void writeList(JsonArray<Long> studentIds){ 
//iterate over studentIds and save them 
} 

Dónde JSONArray es:

public class JsonArray<T> extends ArrayList<T> { 
    public JsonArray(String v) throws IOException { 
     ObjectMapper objectMapper = new ObjectMapper(new MappingJsonFactory()); 
     TypeReference<ArrayList<T>> typeRef = new TypeReference<ArrayList<T>>() {}; 
     ArrayList<T> list = objectMapper.readValue(v, typeRef); 
     for (T x : list) { 
      this.add((T) x); 
     } 
    } 
} 

Esto funciona bien, pero cuando lo hago algo más complicado:

@Path("/studentIds") 
public void writeList(JsonArray<TypeIdentifier> studentIds){ 
//iterate over studentIds and save them by type 
} 

Cuando el Bean es un POJO simple, como

public class TypeIdentifier { 
    private String type; 
    private Long id; 
//getters/setters 
} 

Todo se rompe horriblemente. Convierte todo a LinkedHashMap en lugar de al objeto real. Puedo hacer que funcione si puedo crear manualmente una clase como:

public class JsonArrayTypeIdentifier extends ArrayList<TypeIdentifier> { 
    public JsonArrayTypeIdentifier(String v) throws IOException { 
     ObjectMapper objectMapper = new ObjectMapper(new MappingJsonFactory()); 
     TypeReference<ArrayList<TypeIdentifier>> typeRef = new TypeReference<ArrayList<TypeIdentifier>>(){}; 
     ArrayList<TypeIdentifier> list = objectMapper.readValue(v, typeRef); 
     for(TypeIdentifier x : list){ 
      this.add((TypeIdentifier) x); 
     } 
    } 
} 

Pero yo estoy tratando de mantener este bonito y genérica sin añadir clases adicionales por todas partes. ¿Alguna pista sobre por qué esto está sucediendo solo con la versión genérica?

+0

Ver posible duplicar con una respuesta aceptada: http://stackoverflow.com/questions/6062011/jackson-is-not-deserialising-a-generic-list-that-it-has-serialised –

Respuesta

1

En primer lugar, funciona con Longs porque es una especie de tipo nativo y, como tal, vinculante predeterminado para los números enteros de JSON.

Pero en cuanto a por qué la información de tipo genérico no se pasa correctamente: esto es más probable debido a problemas con la forma API JAX-RS pasa a MessageBodyReader escriba s y s MessageBodyWriter - pasando java.lang.reflect.Type no es (por desgracia!) Lo suficiente como para pase declaraciones genéricas reales (para más información sobre esto, lea this blog entry).

Una fácil solución alternativa es la creación de tipos de ayuda como:

class MyTypeIdentifierArray extends JsonArray<TypeIdentifier> { } 

y el uso de ese tipo - las cosas "sólo trabajo", ya que supertipo información genérica siempre se conserva.

+0

Su trabajo no funciona t trabajo. :(Todavía me da LinkedHashMap como los resultados del análisis. Volver a mi solución larga. Suspiro. –

+0

Definitivamente debería funcionar - ¿me puede mostrar exactamente cómo está tratando de analizarlos? LinkedHashMap solo se devuelve cuando falta información del tipo (o si 'Object.class' se define como tipo). ¿Con qué versión de Jackson está esto? – StaxMan

+0

Jackson versión 1.9.2; –

Cuestiones relacionadas