2010-08-11 16 views
11

Continua da this question.Deserializzazione dell'array json utilizzando gson

Ho problemi deserializzazione il seguente array JSON (Ci scusiamo per la dimensione):

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

Se mi si incolla in un JSON-spettatore, ho questa struttura:

[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 

Ora, l'array contenente gli array con le coordinate ha una dimensione variabile. Quindi ho pensato che in java, questo intero oggetto sarebbe un array, contenente una collezione di array, con ogni array contenente uno Collection<double[]>. Qualcosa come Collection<double[]>[][].

Ma gson non accetta questo. Ottengo il seguente messaggio di errore:

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

Il che sembra strano, come 2.963610 doesnt guardare come un array per me. Ma potrebbe essermi confuso al punto in cui mi sono perso, più o meno ...

risposta

19

Credo di sapere dove il problema proviene, leggendo l'API GSON:

Se l'oggetto che il vostro sono serializzazione/deserializzazione è un ParameterizedType (cioè contiene al almeno un parametro di tipo e maggio essere un array ), quindi è necessario utilizzare toJson (Object, Type) o dal metodo Json (String, Type). Ecco un esempio per la serializzazione e 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); 

Sapendo che

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

Spero che questo aiuti.

+0

Questa potrebbe essere una parte del mio problema. Ho provato questo: Tipo coordinate = nuovo TipoToken >>>>() {}. GetType(); Ma questo mi dà solo un errore-msg dicendo che non è riuscito a deserializzare [jsonstring]. –

+0

Appena inciampato su questa vecchia domanda - ha accettato la tua risposta :) –

1

Penso che avremmo bisogno di più dettagli, come quello che hai scritto per la deserializzazione.

+0

Ho semplicemente scritto questo: Dati dati = nuovo Gson(). Da Json (json.toString(), Data.class); L'oggetto Data è un semplice oggetto java con getter e setter per i campi, che condivide il nome degli attributi json. Coordinate è uno di questi attributi, trovato in una classe Geometry. –

4

Il coordinates in JSON è una matrice tridimensionale. Con Collection<double[]>[][] hai una dimensione troppo alta. Lo stesso Collection è già una dimensione, quindi hai praticamente dichiarato una matrice quadridimensionale.

Con il messaggio di errore, Gson ti sta fondamentalmente dicendo che si aspetta un oggetto per la quarta dimensione, ma invece ha incontrato un doppio.

Il seguente rappresentano validi tridimensionali matrici che deve essere trattato perfettamente dal GSON:

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

Detto questo, preferisco List sopra Collection in questo caso particolare. Con un List puoi garantire che è stato riempito con ordine di inserimento e sarai in grado di get elementi per indice.

+0

Sembra giusto, tranne che il numero di matrici esterne nell'array [coordinate] non è corretto. Nel mio esempio, c'è solo 1. (Va [coordinate] => Array ([0] => Array ([0] => array ...)), ma potrebbe anche contenere, diciamo 2 matrici: [coordinate] => Matrice ([0] => Matrice (...) [1] => Matrice (...)) Spero che questo ha senso? Quindi suppongo che abbiamo bisogno di un'altra raccolta da qualche parte (o lista)? –

+0

Se aggiungo solo un'altra dimensione, come le raccolte private >>>; Ricevo questa eccezione: Eccezione nel thread "main" com.google.gson.JsonParseException: JsonDeserializer [email protected] non è riuscito a deserializzare l'oggetto json 2.963610 dato il tipo com.google.gson.ParameterizedTypeImpl @ b6a924 –

+0

Quindi creare un oggetto wrapper che rappresenta le coordinate che possono contenere i bambini in una raccolta e implementare un deserializzatore personalizzato estendendo 'JsonDeserializer'. – BalusC

2

Secondo guida GSON:

serializzazione e la deserializzazione generici Tipi
Quando si chiama toJSON (obj), GSON chiamate obj.getClass() per ottenere informazioni sui campi per serializzare. Analogamente, è possibile in genere passare l'oggetto MyClass.class nel metodo fromJson(json, MyClass.class). Funziona bene finché l'oggetto è di tipo non generico. Tuttavia, se l'oggetto è di tipo generico, le informazioni sul tipo generico vengono perse a causa di Java Type Erasure. Ecco un esempio che illustra il punto:

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

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

I risultati delle chiamate di cui sopra in un'eccezione di runtime perché GSON invoca myStrings.getClass() per ottenere le informazioni di classe, ma questo metodo restituisce una classe prima, List.class. Ciò significa che Gson non ha modo di sapere che si tratta di un elenco di stringhe e non di semplici oggetti.

È possibile risolvere questo problema specificando il tipo parametrico corretto per il tipo generico. È possibile farlo utilizzando la classe TypeToken.

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

gson.fromJson(json, listType); 

Il linguaggio utilizzato per ottenere listType definisce effettivamente una classe interna locale anonimo contenente un metodo getType() che restituisce il tipo completamente parametrizzato.

Spero che questo aiuti.

Problemi correlati