Désérialisation tableau JSON en utilisant gson
-
27-09-2019 - |
Question
cette question.
Je ne parviens pas désérialisation le tableau JSON suivant (Désolé pour la taille):
"geometry": { "type": "Polygon", "coordinates": [ [ [ 771230.894373, 4422896.962001 ],
[ 804804.852796, 4451159.130080 ], [ 876828.563339, 4417873.954498 ], [ 959794.979827,
4430944.287708 ], [ 910992.515063, 4372980.866944 ], [ 932488.308736, 4357684.778349 ],
[ 918573.372386, 4115663.286966 ], [ 834059.614976, 4013708.358795 ], [ 929360.231044,
3833522.241529 ], [ 1008029.715188, 3776446.653183 ], [ 1061663.445852, 3533717.758754
], [ 1035703.740599, 3519308.069656 ], [ 1095348.723766, 3396028.487184 ], [
1108462.159782, 3230455.268230 ], [ 1083571.121640, 3163122.508021 ], [ 1103953.720405,
3082716.041755 ], [ 1045722.494771, 3020215.642212 ], [ 1117367.719045, 2915275.458735
], [ 1141268.013718, 2827405.304519 ], [ 1286729.192338, 2790314.754276 ], [
1334329.406601, 2695307.513404 ], [ 829417.592210, 2374337.277646 ], [ 647042.870444,
2207530.090128 ], [ 370914.873531, 2152159.656850 ], [ 346669.488436, 2173360.227237 ],
[ 359905.375891, 2251757.174668 ], [ 199905.871774, 2309591.361246 ], [ 129963.835709,
2361036.252651 ], [ 130208.738589, 2404106.913263 ], [ -964785.432600, 3159802.671416
], [ -964829.960396, 3338713.127631 ], [ -851005.781060, 3424742.002477 ], [ -
616522.405653, 3491025.523892 ], [ -547749.224241, 3569019.334331 ], [ -403724.067052,
3628920.873754 ], [ -423973.082428, 3724062.779415 ], [ -333893.350478, 3741450.793542
], [ -317696.364567, 3774909.265404 ], [ -131414.328674, 3777826.527844 ], [ -
112467.751341, 3830221.719769 ], [ -185682.580436, 3930014.456814 ], [ -194499.084106,
4129581.855629 ], [ -245950.952751, 4175549.526399 ], [ -42303.076294, 4287174.981681
], [ -11222.674464, 4271148.905617 ], [ 131633.628071, 4371332.547494 ], [
433220.392528, 4427574.250017 ], [ 593119.709103, 4389089.571176 ], [ 719645.442339,
4451856.882422 ], [ 771230.894373, 4422896.962001 ] ] ] }
Si je le coller dans un JSON-spectateur, je reçois cette structure:
[geometry]
...
[coordinates] => Array
(
[0] => Array
(
[0] => Array
(
[0] => 771230.894373
[1] => 4422896.962001
)
[1] => Array
(
[0] => 804804.852796
[1] => 4451159.13008
)
...
[n] => Array
[n] => Array
Maintenant, le tableau contenant les tableaux avec les coordonnées a une taille variable. Alors je me suis que java, cet objet tout whould être un tableau, contenant une collection de tableaux, chaque tableau contenant un Collection<double[]>
. Quelque chose comme Collection<double[]>[][].
Mais gson n'accepte pas. Je reçois le message d'erreur suivant:
Exception in thread "main" com.google.gson.JsonParseException: Expecting object but
found array: 2.963610
Ce qui semble bizarre, comme regard 2.963610
ne marche pas comme un tableau pour moi. Mais il aurait pu me confondre au point où je suis perdu, plus ou moins ...
La solution
Je pense que je sais où votre problème vient, la lecture de l'API Gson:
Si l'objet que vous êtes sérialisation / désérialisation est un ParameterizedType (à savoir contenant au moins un paramètre de type et peuvent être un tableau), alors vous devez utiliser la toJson (Object, Type) ou Procédé fromJson (String, Type). Voici un exemple pour la sérialisation et la deserialing un ParameterizedType:
Type listType = new TypeToken<LinkedList>() {}.getType();
List target = new LinkedList();
target.add("blah");
Gson gson = new Gson();
String json = gson.toJson(target, listType);
List target2 = gson.fromJson(json, listType);
Sachant que
Type typeOfCollectionOfFoo = new TypeToken<Collection<Foo>>(){}.getType()
Hope this helps.
Autres conseils
Le coordinates
en JSON est une matrice à trois dimensions. Avec Collection<double[]>[][]
vous allez une dimension trop loin. Le Collection
lui-même est déjà une dimension, de sorte que vous avez essentiellement une matrice déclarée quatre dimensions.
Avec le message d'erreur, Gson vous dit essentiellement qu'il attend un objet pour la quatrième dimension, mais au lieu a rencontré un double.
Les éléments suivants représentent valides matrices en trois dimensions qui doivent être parfaitement gérées par Gson:
-
private double[][][] coordinates;
(recommandé) -
private Collection<double[]>[] coordinates;
-
private Collection<double[][]> coordinates;
-
private Collection<Collection<double[]>> coordinates;
-
private Collection<Collection<Collection<Double>>> coordinates;
Cela dit, je préférerais List
Collection
dans ce cas particulier . Avec un List
vous pouvez garantir qu'il a été rempli avec l'ordre d'insertion et vous serez en mesure de get éléments par index.
Selon le Guide de l'utilisateur Gson:
sérialisation et désérialisation types génériques
Lorsque vous appelez toJson (obj), Gson appelle obj.getClass()
pour obtenir des informations sur les champs à serialize. De même, vous pouvez généralement passer l'objet MyClass.class
dans la méthode fromJson(json, MyClass.class)
. Cela fonctionne très bien tant que l'objet est un type non générique. Toutefois, si l'objet est d'un type générique, les informations de type générique est perdu à cause de Java type Erasure . Voici un exemple qui illustre le point:
List<String> myStrings = new List<String>();
gson.toJson(myStrings); // Will cause a runtime exception
gson.fromJson(json, myStrings.getClass());
Les résultats de l'appel ci-dessus à une exception d'exécution parce que Gson invoque pour obtenir sa myStrings.getClass()
information de classe, mais cette méthode retourne une classe première, List.class
. Cela signifie que Gson n'a aucun moyen de savoir que ceci est une liste de chaînes, et non des objets simples.
Vous pouvez résoudre ce problème en spécifiant le type paramétrées correct pour votre type générique. Vous pouvez le faire en utilisant la classe TypeToken
.
Type listType = new TypeToken<List<String>>() {}.getType();
gson.toJson(myStrings, listType);
gson.fromJson(json, listType);
Le langage utilisé pour obtenir listType
définit en fait une classe interne locale anonyme contenant une getType()
méthode qui retourne le type entièrement paramétrés.
Hope this helps.
Je pense que nous aurions besoin de plus de détails, comme ce que vous avez écrit pour le désérialisation.