Deserializar JSON a ArrayList usando Jackson

Tengo una clase Java MyPojo que estoy interesado en deserializar de JSON. He configurado una clase especial MixIn, MyPojoDeMixIn , para ayudarme con la deserialización. MyPojo solo tiene variables de instancia int y String combinadas con getters y setters adecuados. MyPojoDeMixIn ve así:

 public abstract class MyPojoDeMixIn { MyPojoDeMixIn( @JsonProperty("JsonName1") int prop1, @JsonProperty("JsonName2") int prop2, @JsonProperty("JsonName3") String prop3) {} } 

En mi cliente de prueba, hago lo siguiente, pero, por supuesto, no funciona en tiempo de comstackción porque hay una JsonMappingException relacionada con un tipo no coincidente.

 ObjectMapper m = new ObjectMapper(); m.getDeserializationConfig().addMixInAnnotations(MyPojo.class,MyPojoDeMixIn.class); try { ArrayList arrayOfPojo = m.readValue(response, MyPojo.class); } catch (Exception e) { System.out.println(e) } 

Soy consciente de que podría aliviar este problema creando un objeto de “Respuesta” que solo tiene un ArrayList , pero luego tendría que crear estos objetos algo inútiles para cada tipo que quiera devolver.

También busqué en línea JacksonInFiveMinutes, pero pasé un tiempo terrible entendiendo las cosas sobre Map y cómo se relaciona con mi problema. Si no puede decirlo, soy completamente nuevo en Java y procedo de un entorno Obj-C. Mencionan específicamente:

Además de vincularse a POJO y tipos “simples”, existe una variante adicional: la de vincular a contenedores generics (tipados). Este caso requiere un manejo especial debido a la llamada eliminación de tipos (utilizada por Java para implementar generics de una manera un tanto retrógrada), lo que le impide usar algo como Collection.class (que no se comstack).

Por lo tanto, si desea vincular datos a un Mapa, deberá usar:

 Map result = mapper.readValue(src, new TypeReference<Map>() { }); 

¿Cómo puedo deserializar directamente a ArrayList ?

Puede deserializar directamente a una lista utilizando el contenedor TypeReference . Un método de ejemplo:

 public static  T fromJSON(final TypeReference type, final String jsonPacket) { T data = null; try { data = new ObjectMapper().readValue(jsonPacket, type); } catch (Exception e) { // Handle the problem } return data; } 

Y se usa así:

 final String json = ""; Set properties = fromJSON(new TypeReference>() {}, json); 

.

TypeReference Javadoc

Otra forma es usar una matriz como un tipo, por ejemplo:

 ObjectMapper objectMapper = new ObjectMapper(); MyPojo[] pojos = objectMapper.readValue(json, MyPojo[].class); 

De esta forma evitará todas las molestias con el objeto Type, y si realmente necesita una lista, siempre puede convertir la matriz en una lista de la siguiente manera:

 List pojoList = Arrays.asList(pojos); 

En mi humilde opinión esto es mucho más legible.

Y para que sea una lista real (que se puede modificar, consulte las limitaciones de Arrays.asList() ), haga lo siguiente:

 List mcList = new ArrayList<>(Arrays.asList(pojos)); 

Esta variante parece más simple y elegante.

 CollectionType typeReference = TypeFactory.defaultInstance().constructCollectionType(List.class, Dto.class); List resultDto = objectMapper.readValue(content, typeReference); 

Yo también tengo el mismo problema. Tengo un json que se debe convertir a ArrayList.

La cuenta se ve así.

 Account{ Person p ; Related r ; } Person{ String Name ; Address a ; } 

Todas las clases anteriores se han anotado correctamente. He intentado con TypeReference> () {} pero no funciona.

Me da Arraylist pero ArrayList tiene unHashMap enlazado que contiene algunos hashmaps más enlazados que contienen los valores finales.

Mi código es el siguiente:

 public T unmarshal(String responseXML,String c) { ObjectMapper mapper = new ObjectMapper(); AnnotationIntrospector introspector = new JacksonAnnotationIntrospector(); mapper.getDeserializationConfig().withAnnotationIntrospector(introspector); mapper.getSerializationConfig().withAnnotationIntrospector(introspector); try { this.targetclass = (T) mapper.readValue(responseXML, new TypeReference>() {}); } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return this.targetclass; } 

Finalmente resolví el problema. Puedo convertir la Lista en Json String directamente en ArrayList de la siguiente manera:

 JsonMarshallerUnmarshaller{ T targetClass ; public ArrayList unmarshal(String jsonString) { ObjectMapper mapper = new ObjectMapper(); AnnotationIntrospector introspector = new JacksonAnnotationIntrospector(); mapper.getDeserializationConfig().withAnnotationIntrospector(introspector); mapper.getSerializationConfig().withAnnotationIntrospector(introspector); JavaType type = mapper.getTypeFactory(). constructCollectionType(ArrayList.class, targetclass.getClass()) ; try { Class c1 = this.targetclass.getClass() ; Class c2 = this.targetclass1.getClass() ; ArrayList temp = (ArrayList) mapper.readValue(jsonString, type); return temp ; } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null ; } } 

Esto funciona para mí

 @Test public void cloneTest() { List parts = new ArrayList(); Part part1 = new Part(1); parts.add(part1); Part part2 = new Part(2); parts.add(part2); try { ObjectMapper objectMapper = new ObjectMapper(); String jsonStr = objectMapper.writeValueAsString(parts); List cloneParts = objectMapper.readValue(jsonStr, new TypeReference>() {}); } catch (Exception e) { //fail("failed."); e.printStackTrace(); } //TODO: Assert: compare both list values. }