views:

510

answers:

3

Continuing from this question.

I'm having trouble deserializing the following json array (Sorry for the size):

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

If I paste it into a json-viewer, I get this 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

Now, the array containing the arrays with the coordinates has a variable size. So I figured that in java, this whole object whould be an array, containing a collection of arrays, with each array containing a Collection<double[]>. Something like Collection<double[]>[][].

But gson does not accept this. I get the following error message:

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

Which seems weird, as 2.963610 doesnt look like an array to me. But it might have confused me to the point where I'm lost, more or less...

+1  A: 

I think we'd need more details, such as what you wrote for the deserialization.

Nicolas C.
I simply wrote this:Data data = new Gson().fromJson(json.toString(),Data.class);The Data object is a simple java-object with getters and setters for the fields, sharing the name of the json attributes. Coordinates is one of these attributes, found in a Geometry class.
Frederik Wordenskjold
A: 

I think I know where your problem comes from, reading the Gson API :

If the object that your are serializing/deserializing is a ParameterizedType (i.e. contains at least one type parameter and may be an array) then you must use the toJson(Object, Type) or fromJson(String, Type) method. Here is an example for serializing and deserialing a ParameterizedType:

Type listType = new TypeToken>() {}.getType();
List target = new LinkedList();
target.add("blah");

Gson gson = new Gson();
String json = gson.toJson(target, listType);
List target2 = gson.fromJson(json, listType);

Knowing that

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

Hope this helps.

Nicolas C.
This might be a part of my problem. I've tried this:Type coordinates = new TypeToken<Collection<Collection<Collection<Collection<Double>>>>>(){}.getType();But this just gives me an error-msg saying that it failed to deserialize [jsonstring].
Frederik Wordenskjold
+1  A: 

The coordinates in JSON is a three-dimensional matrix. With Collection<double[]>[][] you're going one dimension too far. The Collection itself is already one dimension, so you've basically declared a four-dimensional matrix.

With the error message, Gson is basically telling you that it is expecting an object for the fourth dimension, but it instead encountered a double.

The following represent valid three-dimensional matrices which should be perfectly handled by Gson:

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

That said, I would prefer List above Collection in this particular case. With a List you can guarantee that it's been filled with insertion order and you'll be able to get elements by index.

BalusC
This seems about right, except that the number of outer arrays in the [coordinates] array isnt fixed. In my example, there is only 1. (It goes [coordinates] => Array( [0] => Array ( [0] => array ... ) ), but it could also contain, say 2 arrays:[coordinates] => Array ( [0] => Array ( ... ) [1] => Array ( ... ) )Hope this makes sense? So I guess we need another collection somewhere (or list)?
Frederik Wordenskjold
If I just add another dimension, like private Collection<Collection<Collection<Collection<Double>>>> coordinates; I get this exception:Exception in thread "main" com.google.gson.JsonParseException: The JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter@929206 failed to deserialized json object 2.963610 given the type com.google.gson.ParameterizedTypeImpl@b6a924
Frederik Wordenskjold
Then create a wrapper object representing the coordinates which can hold children in a collection and implement a custom deserializer by extending `JsonDeserializer`.
BalusC