2010-08-11 4 views
11

Fortsetzung von this question.Deserialisieren von JSON-Arrays unter Verwendung von Gson

Ich habe Probleme beim Deserialisieren der folgende json Array (Sorry für die Größe):

"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 ] ] ] } 

Wenn ich es in einen Json-Viewer einfügen, erhalte ich diese Struktur:

[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 

Jetzt hat das Array, das die Arrays mit den Koordinaten enthält, eine variable Größe. Also dachte ich mir, dass in Java das ganze Objekt ein Array sein sollte, das eine Sammlung von Arrays enthält, wobei jedes Array einen Collection<double[]> enthält. Etwas wie Collection<double[]>[][].

Aber gson akzeptiert dies nicht. Ich erhalte die folgende Fehlermeldung:

Exception in thread "main" com.google.gson.JsonParseException: Expecting object but  
found array: 2.963610 

Welche seltsam scheint, als 2.963610 tut mir wie ein Array aus. Aber es könnte mich zu dem Punkt verwirrt haben, wo ich mehr oder weniger verloren bin ...

Antwort

19

Ich glaube, ich weiß, wo das Problem herkommt, die Gson API zu lesen:

Wenn das Objekt das sind Serialisierung/Deserialisierung ein ParameterizedType ist (dh zumin mindestens einen Typ Parameter und kann ein Array sein), dann müssen Sie die toJson (Object, Type) oder fromJson (String, Type) -Methode verwenden. Hier ist ein Beispiel für die Serialisierung und deserialing eine 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); 

Zu wissen, dass

Type typeOfCollectionOfFoo = new TypeToken<Collection<Foo>>(){}.getType() 

Hoffnung, das hilft.

+0

Dies könnte ein Teil meines Problems sein. Ich habe es versucht: Type coordinates = new TypeToken >>>>() {}. GetType(); Aber das gibt mir nur eine Fehlermeldung, die besagt, dass es [jsonstring] nicht deserialisieren konnte. –

+0

Gerade gestolpert über diese alte Frage - Ihre Antwort akzeptiert :) –

1

Ich denke, wir würden mehr Details benötigen, wie zum Beispiel was du für die Deserialisierung geschrieben hast.

+0

Ich schrieb einfach: Data data = new Gson(). Aus Json (json.toString(), Data.class); Das Datenobjekt ist ein einfaches Java-Objekt mit Gettern und Setter für die Felder, die den Namen der JSON-Attribute teilen. Koordinaten ist eines dieser Attribute in einer Geometrieklasse. –

4

Die coordinates in JSON ist eine dreidimensionale Matrix. Mit Collection<double[]>[][] gehen Sie eine Dimension zu weit. Die Collection selbst ist bereits eine Dimension, also haben Sie im Grunde eine vierdimensionale Matrix deklariert.

Mit der Fehlermeldung, Gson sagt Ihnen im Grunde, dass es ein Objekt für die vierte Dimension erwartet, aber stattdessen ein Double gefunden.

Die folgende repräsentieren gültige dreidimensionale Matrizen, die perfekt von Gson behandelt werden sollte:

  • private double[][][] coordinates; (empfohlen)
  • private Collection<double[]>[] coordinates;
  • private Collection<double[][]> coordinates;
  • private Collection<Collection<double[]>> coordinates;
  • private Collection<Collection<Collection<Double>>> coordinates;

Das sagte, würde ich List über Collection in diesem speziellen Fall bevorzugen. Mit einer List können Sie garantieren, dass es mit Anzeigenauftrag gefüllt wurde und Sie können get Elemente nach Index.

+0

Dies scheint in etwa richtig, außer dass die Anzahl der äußeren Arrays in der [Koordinaten] Array nicht fest ist. In meinem Beispiel gibt es nur 1. (Es geht [Koordinaten] => Array ([0] => Array ([0] => Array ...)), aber es könnte auch enthalten, sagen zwei Arrays: [Koordinaten] => Array ([0] => Array (...) [1] => Array (...)) Hoffen, dass dieses macht Sinn? Ich nehme an, wir brauchen irgendwo eine andere Sammlung (oder Liste)? –

+0

Wenn ich nur eine andere Dimension hinzufügen, wie private Sammlung >>> Koordinaten; Ich bekomme diese Ausnahme: Ausnahme im Thread "Haupt" com.google.gson.JsonParseException: Die JsonDeserializer [email protected] fehlgeschlagen deserialisierten JSON-Objekt 2.963610 angesichts der Art com.google.gson.ParameterizedTypeImpl @ b6a924 –

+0

Erstellen Sie dann ein Wrapper-Objekt, das die Koordinaten darstellt, die untergeordnete Elemente in einer Auflistung enthalten können, und implementieren Sie einen benutzerdefinierten Deserializer, indem Sie 'JsonDeserializer' erweitern. – BalusC

2

Nach Gson Bedienungsanleitung:

Serialisieren und Deserialisieren generische Typen
Wenn Sie toJson nennen (obj), ruft Gson obj.getClass() Informationen über die Felder zu erhalten serialisiert. In ähnlicher Weise können Sie in der Regel MyClass.class Objekt in der fromJson(json, MyClass.class) Methode übergeben. Dies funktioniert gut, solange das Objekt ein nicht-generischer Typ ist. Wenn das Objekt jedoch einen generischen Typ aufweist, gehen die Informationen des generischen Typs aufgrund von Java Type Erasure verloren. Hier ist ein Beispiel veranschaulicht den Punkt:

List<String> myStrings = new List<String>(); 
gson.toJson(myStrings); // Will cause a runtime exception 

gson.fromJson(json, myStrings.getClass()); 

Der obige Aufruf führt zu einer Laufzeitausnahme, weil Gson myStrings.getClass() ruft seine Klasseninformationen zu erhalten, aber diese Methode gibt eine rohe Klasse, List.class. Dies bedeutet, dass Gson nicht wissen kann, dass es sich um eine Liste von Strings und nicht um einfache Objekte handelt.

Sie können dieses Problem lösen, indem Sie den korrekten parametrisierten Typ für Ihren generischen Typ angeben. Sie können dies tun, indem Sie die Klasse TypeToken verwenden.

Type listType = new TypeToken<List<String>>() {}.getType(); 
gson.toJson(myStrings, listType); 

gson.fromJson(json, listType); 

Das Idiom verwendet listType erhalten definiert tatsächlich eine anonyme lokale innere Klasse ein Verfahren getType() enthält, das den vollständig parametrisierten Typ zurückgibt.

Hoffe, das hilft.

Verwandte Themen