2010-08-11 35 views
11

Continuando de this question.Deserialización de la matriz json usando gson

Tengo problemas para deserializar la siguiente matriz JSON (Lo siento por el tamaño):

"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 me pega en un JSON-espectador, me sale esta estructura:

[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 

Ahora, la matriz que contiene las matrices con las coordenadas tiene un tamaño variable. Así que pensé que en Java, todo este objeto sería una matriz, que contiene una colección de matrices, con cada matriz que contiene un Collection<double[]>. Algo así como Collection<double[]>[][].

Pero GSON no acepta esto. Me sale el siguiente mensaje de error:

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

que parece raro, como 2.963610 imposible parece una matriz para mí. Pero puede ser que me han confundido hasta el punto en que estoy perdido, más o menos ...

Respuesta

19

creo que sé dónde está su problema viene de, la lectura de la API Gson:

Si el objeto de que su son serialización/deserializar es un ParameterizedType (es decir, contiene al menos un parámetro de tipo y mayo sea ​​una matriz ) luego debe usar el aJson (Objeto, Tipo) o del método Json (Serie, Tipo). Aquí es un ejemplo para serializar y 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); 

Sabiendo que

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

Espero que esto ayude.

+0

Esto podría ser parte de mi problema. Intenté esto: Type coordinates = new TypeToken >>>>() {}. GetType(); Pero esto me da un error-msg diciendo que no se pudo deserializar [jsonstring]. –

+0

Acabo de tropezar con esta vieja pregunta: acepté tu respuesta :) –

1

Creo que necesitaríamos más detalles, como por ejemplo lo que ha escrito para la deserialización.

+0

Simplemente escribí esto: Datos de datos = new Gson(). FromJson (json.toString(), Data.class); El objeto Data es un simple objeto java con getters y setters para los campos, compartiendo el nombre de los atributos json. Coordenadas es uno de estos atributos, que se encuentra en una clase de Geometría. –

4

El coordinates en JSON es una matriz tridimensional. Con Collection<double[]>[][] vas una dimensión demasiado lejos. El Collection ya tiene una dimensión, por lo que básicamente has declarado una matriz de cuatro dimensiones.

Con el mensaje de error, Gson es, básicamente, que le dice que se está a la espera un objeto de la cuarta dimensión, pero en cambio se encontró con un doble.

La siguiente representan tres dimensiones matrices válidas que deben ser perfectamente manejados por Gson:

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

Dicho esto, yo preferiría List anterior Collection en este caso particular. Con un List puede garantizar que se ha completado con el orden de inserción y podrá get elementos por índice.

+0

Esto parece correcto, excepto que el número de matrices externas en la matriz [coordenadas] no está fijo. En mi ejemplo, solo hay 1. (Va [coordenadas] => Matriz ([0] => Matriz ([0] => matriz ...)), pero también podría contener, por ejemplo, 2 matrices: [coordenadas] => Matriz ([0] => Matriz (...) [1] => Matriz (...)) Espero que esto ¿tiene sentido? ¿Entonces creo que necesitamos otra colección en algún lugar (o lista)? –

+0

Si acabo de agregar otra dimensión, como colección privada >>> coordenadas; Obtengo esta excepción: Excepción en el hilo "principal" com.google.gson.JsonParseException: El JsonDeserializer [email protected] no pudo deserializar el objeto json 2.963610 dado el tipo com.google.gson.ParameterizedTypeImpl @ b6a924 –

+0

A continuación, cree un objeto envoltorio que represente las coordenadas que pueden contener elementos secundarios en una colección e implemente un deserializador personalizado ampliando 'JsonDeserializer'. – BalusC

2

Según la guía del usuario Gson:

serializar y deserializar genéricos Tipos
Cuando se llama a toJson (obj), Gson llamadas obj.getClass() para obtener información acerca de los campos de serializar. Del mismo modo, normalmente puede pasar el objeto MyClass.class en el método fromJson(json, MyClass.class). Esto funciona bien siempre que el objeto sea de tipo no genérico. Sin embargo, si el objeto es de tipo genérico, la información de tipo genérico se pierde debido a Java Type Erasure. Este es un ejemplo que ilustra el punto:

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

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

La llamada anterior resulta en una excepción de tiempo de ejecución porque Gson invoca myStrings.getClass() para obtener su información de clase, pero este método devuelve una clase cruda, List.class. Esto significa que Gson no tiene forma de saber que esta es una lista de cadenas y no de objetos simples.

Puede resolver este problema especificando el tipo parametrizado correcto para su tipo genérico. Puede hacerlo utilizando la clase TypeToken.

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

gson.fromJson(json, listType); 

El lenguaje utilizado para obtener listType en realidad define una clase interna local de anónimo que contiene un método getType() que devuelve el tipo completamente parametrizada.

Espero que esto ayude.

Cuestiones relacionadas