Désérialiser JSON en ArrayList en utilisant Jackson

J’ai une classe Java MyPojo que je suis intéressé à désérialiser à partir de JSON. J’ai configuré une classe spéciale MixIn, MyPojoDeMixIn , pour m’aider avec la désérialisation. MyPojo n’a que des variables d’instance int et Ssortingng combinées avec des getters et des setters appropriés. MyPojoDeMixIn ressemble à ceci:

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

Dans mon client de test, je fais ce qui suit, mais bien sûr, cela ne fonctionne pas au moment de la compilation car il existe une JsonMappingException liée à une incompatibilité de type.

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

Je suis conscient que je pourrais atténuer ce problème en créant un object “Response” ArrayList uniquement un ArrayList , mais je devrais alors créer ces objects quelque peu inutiles pour chaque type que je veux renvoyer.

J’ai aussi regardé en ligne JacksonInFiveMinutes mais j’ai eu beaucoup de mal à comprendre les choses sur Map et leur relation avec mon problème. Si vous ne pouvez pas le savoir, je suis totalement nouveau sur Java et je viens d’un arrière-plan Obj-C. Ils mentionnent spécifiquement:

Outre la liaison à des POJO et des types “simples”, il existe une variante supplémentaire: celle de la liaison avec des conteneurs génériques (typés). Ce cas nécessite une gestion spéciale en raison de ce qu’on appelle le type effacement (utilisé par Java pour implémenter les génériques de manière quelque peu rétrocompatible), ce qui vous empêche d’utiliser quelque chose comme Collection.class (qui ne comstack pas).

Donc, si vous souhaitez lier des données dans une carte, vous devrez utiliser:

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

Comment puis-je désérialiser directement sur ArrayList ?

Vous pouvez désérialiser directement une liste en utilisant l’encapsuleur TypeReference . Un exemple de méthode:

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

Et est utilisé ainsi:

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

.

TypeReference Javadoc

Une autre méthode consiste à utiliser un tableau comme un type, par exemple:

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

De cette façon, vous évitez tout problème avec l’object Type et si vous avez vraiment besoin d’une liste, vous pouvez toujours convertir le tableau en une liste en:

 List pojoList = Arrays.asList(pojos); 

IMHO c’est beaucoup plus lisible.

Et pour en faire une liste réelle (qui peut être modifiée, voir les limitations de Arrays.asList() ), procédez comme suit:

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

Cette variante semble plus simple et élégante.

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

J’ai aussi le même problème. J’ai un json qui doit être converti en ArrayList.

Compte ressemble à ceci.

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

Toutes les classes ci-dessus ont été annotées correctement. J’ai essayé TypeReference> () {} mais ne fonctionne pas.

Cela me donne Arraylist mais ArrayList a un linkedHashMap qui contient d’autres hashmaps liés contenant des valeurs finales.

Mon code est comme suit:

 public T unmarshal(Ssortingng responseXML,Ssortingng 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; } 

J’ai finalement résolu le problème. Je suis capable de convertir la liste dans Json Ssortingng directement en ArrayList comme suit:

 JsonMarshallerUnmarshaller{ T targetClass ; public ArrayList unmarshal(Ssortingng jsonSsortingng) { 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(jsonSsortingng, type); return temp ; } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null ; } } 

Cela fonctionne pour moi.

 @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(); Ssortingng jsonStr = objectMapper.writeValueAsSsortingng(parts); List cloneParts = objectMapper.readValue(jsonStr, new TypeReference>() {}); } catch (Exception e) { //fail("failed."); e.printStackTrace(); } //TODO: Assert: compare both list values. }