Je demande des données à un serveur qui renvoie des données au format JSON. Transposer un HashMap en JSON lors de la demande n'a pas été difficile du tout, mais l'autre sens semble être un peu délicat. La réponse JSON ressemble à ceci:
{
"header" : {
"alerts" : [
{
"AlertID" : "2",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
},
{
"AlertID" : "3",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
}
],
"session" : "0bc8d0835f93ac3ebbf11560b2c5be9a"
},
"result" : "4be26bc400d3c"
}
Quelle serait la manière la plus simple d'accéder à ces données? J'utilise le module GSON.
Map<String,Object> result = new Gson().fromJson(json, Map.class);
fonctionne avec gson 2.6.2.Réponses:
Voici:
la source
TypeToken
- cela implique un casting implicite à l'intérieur.{"k1":"apple","k2":"orange"}
Ce code fonctionne:
la source
Map<String, Object>
parce que si le json n'est pas seulement des cordes, vous obtenez une erreurTypeToken
.Je sais que c'est une question assez ancienne, mais je cherchais une solution pour désérialiser génériquement le JSON imbriqué en un
Map<String, Object>
, et je n'ai rien trouvé.De la façon dont mon désérialiseur yaml fonctionne, il définit par défaut les objets JSON
Map<String, Object>
lorsque vous ne spécifiez pas de type, mais gson ne semble pas le faire. Heureusement, vous pouvez l'accomplir avec un désérialiseur personnalisé.J'ai utilisé le désérialiseur suivant pour désérialiser naturellement tout, par défaut
JsonObject
s àMap<String, Object>
etJsonArray
s àObject[]
s, où tous les enfants sont désérialisés de la même manière.Le désordre à l'intérieur de la
handlePrimitive
méthode est de s'assurer que vous n'obtenez jamais qu'un Double ou un Entier ou un Long, et pourrait probablement être mieux, ou au moins simplifié si vous êtes d'accord avec l'obtention de BigDecimals, qui je crois est la valeur par défaut.Vous pouvez enregistrer cet adaptateur comme:
Et puis appelez-le comme:
Je ne sais pas pourquoi ce n'est pas le comportement par défaut dans gson, car c'est dans la plupart des autres bibliothèques de sérialisation semi-structurées ...
la source
Avec Gson 2.7 de Google (probablement des versions antérieures aussi, mais j'ai testé avec la version 2.7 actuelle), c'est aussi simple que:
Qui retourne un
Map
typecom.google.gson.internal.LinkedTreeMap
et fonctionne récursivement sur les objets imbriqués, les tableaux, etc.J'ai exécuté l'exemple OP comme ceci (simplement remplacé double- par des guillemets simples et supprimé les espaces blancs):
Et obtenu la sortie suivante:
la source
Mise à jour pour la nouvelle bibliothèque Gson:
Vous pouvez maintenant analyser directement Json imbriqué dans Map, mais vous devez être conscient au cas où vous essayez d'analyser Json pour
Map<String, Object>
taper: cela lèvera une exception. Pour résoudre ce problème, déclarez simplement le résultat commeLinkedTreeMap
type. Exemple ci-dessous:la source
Map<String,Object> result = gson.fromJson(json , Map.class);
. Utilisation de gson 2.6.2.J'avais exactement la même question et je me suis retrouvé ici. J'ai eu une approche différente qui semble beaucoup plus simple (peut-être des versions plus récentes de gson?).
avec le json suivant
Le suivant
les sorties
Vous pouvez vérifier dynamiquement en utilisant instanceof lors de la navigation dans votre jsonObject. Quelque chose comme
Cela fonctionne pour moi, donc cela doit fonctionner pour vous ;-)
la source
Ci-dessous est pris en charge depuis gson 2.8.0
la source
Essayez ceci, cela fonctionnera. Je l'ai utilisé pour Hashtable .
Remplacez KioskStatusResource dans votre classe et Integer dans votre classe de clés.
la source
Voici ce que j'utilise:
la source
Voici une doublure qui le fera:
la source
new TypeToken<HashMap<String, Object>>(){}
cela créera une nouvelle sous-classe en ligne, et tous lesJ'ai surmonté un problème similaire avec un JsonDeSerializer personnalisé. J'ai essayé de le rendre un peu générique mais toujours pas suffisant. C'est une solution qui correspond à mes besoins.
Tout d'abord, vous devez implémenter un nouveau JsonDeserializer pour les objets Map.
Et la méthode de désérialisation ressemblera à ceci:
L'inconvénient de cette solution est que la clé de ma carte est toujours de type "String". Cependant, en changeant certaines choses, quelqu'un peut le rendre générique. De plus, je dois dire que la classe de la valeur doit être passée dans le constructeur. Ainsi, la méthode
getMyType()
dans mon code renvoie le type des valeurs de la carte, qui a été passé dans le constructeur.Vous pouvez référencer cet article Comment écrire un désérialiseur JSON personnalisé pour Gson? afin d'en savoir plus sur les désérialiseurs personnalisés.
la source
Vous pouvez utiliser cette classe à la place :) (gère les listes paires, les listes imbriquées et json)
Pour convertir votre chaîne JSON en hashmap, utilisez ceci:
la source
C'est plus un addendum à la réponse de Kevin Dolan qu'une réponse complète, mais j'avais du mal à extraire le type du numéro. Voici ma solution:
la source
la source
JSONObject utilise généralement en
HashMap
interne pour stocker les données. Vous pouvez donc l'utiliser comme carte dans votre code.Exemple,
la source
J'ai utilisé ce code:
la source