Java 使用 gson 反序列化 json 数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3458930/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Deserializing json array using gson
提问by Frederik Wordenskjold
Continuing from this question.
从这个问题继续。
I'm having trouble deserializing the following json array (Sorry for the size):
我在反序列化以下 json 数组时遇到问题(对不起,大小):
"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:
如果我将其粘贴到 json-viewer 中,则会得到以下结构:
[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[]>[][].
现在,包含坐标数组的数组具有可变大小。所以我认为在 java 中,整个对象应该是一个数组,包含一组数组,每个数组包含一个Collection<double[]>
. 就像是Collection<double[]>[][].
But gson does not accept this. I get the following error message:
但 gson 不接受这一点。我收到以下错误消息:
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...
这看起来很奇怪,因为2.963610
对我来说看起来不像一个数组。但它可能让我困惑到迷失的地步,或多或少......
采纳答案by Nicolas C.
I think I know where your problem comes from, reading the Gson API :
我想我知道你的问题来自哪里,阅读 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:
如果您正在序列化/反序列化的对象是 ParameterizedType(即包含至少一个类型参数并且可能是一个数组),那么您必须使用 toJson(Object, Type) 或 fromJson(String, Type) 方法。这是序列化和反序列化 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);
Knowing that
知道
Type typeOfCollectionOfFoo = new TypeToken<Collection<Foo>>(){}.getType()
Hope this helps.
希望这可以帮助。
回答by Nicolas C.
I think we'd need more details, such as what you wrote for the deserialization.
我认为我们需要更多详细信息,例如您为反序列化编写的内容。
回答by BalusC
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.
的coordinates
在JSON是三维矩阵。随着Collection<double[]>[][]
你要去一个维度太远。在Collection
本身已经是一个维度,所以你已经基本宣告了四维矩阵。
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.
通过错误消息,Gson 基本上是在告诉您它正在期待一个第四维的对象,但它却遇到了一个 double。
The following represent valid three-dimensional matrices which should be perfectly handled by Gson:
以下表示应由 Gson 完美处理的有效三维矩阵:
private double[][][] coordinates;
(recommended)private Collection<double[]>[] coordinates;
private Collection<double[][]> coordinates;
private Collection<Collection<double[]>> coordinates;
private Collection<Collection<Collection<Double>>> coordinates;
private double[][][] coordinates;
(受到推崇的)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 getelements by index.
也就是说,在这种特殊情况下,我更喜欢List
上面的内容Collection
。使用 aList
您可以保证它已被插入顺序填充,并且您将能够通过索引获取元素。
回答by Isaiah
According to Gson user guide:
根据 Gson 用户指南:
Serializing and Deserializing Generic Types
When you call toJson(obj), Gson calls obj.getClass()
to get information about the fields to serialize. Similarly, you can typically pass MyClass.class
object in the fromJson(json, MyClass.class)
method. This works fine as long as the object is a non-generic type. However, if the object is of a generic type, then the generic type information is lost because of Java Type Erasure. Here is an example illustrating the point:
序列化和反序列化泛型类型
当您调用 toJson(obj) 时,Gson 会调用obj.getClass()
以获取有关要序列化的字段的信息。同样,您通常可以MyClass.class
在fromJson(json, MyClass.class)
方法中传递对象。只要对象是非泛型类型,就可以正常工作。但是,如果对象是泛型类型,那么泛型类型信息会因为Java 类型擦除而丢失。这是一个说明这一点的例子:
List<String> myStrings = new List<String>();
gson.toJson(myStrings); // Will cause a runtime exception
gson.fromJson(json, myStrings.getClass());
The above call results in a runtime exception because Gson invokes myStrings.getClass()
to get its class information, but this method returns a raw class, List.class
. This means that Gson has no way of knowing that this is a list of Strings, and not plain objects.
上述调用导致运行时异常,因为 Gson 调用myStrings.getClass()
以获取其类信息,但此方法返回一个原始类List.class
. 这意味着 Gson 无法知道这是一个字符串列表,而不是普通对象。
You can solve this problem by specifying the correct parameterized type for your generic type. You can do this by using the TypeToken
class.
您可以通过为泛型类型指定正确的参数化类型来解决此问题。您可以通过使用TypeToken
该类来做到这一点。
Type listType = new TypeToken<List<String>>() {}.getType();
gson.toJson(myStrings, listType);
gson.fromJson(json, listType);
The idiom used to get listType
actually defines an anonymous local inner class containing a method getType()
that returns the fully parameterized type.
用于 get 的习惯用法listType
实际上定义了一个匿名本地内部类,其中包含一个getType()
返回完全参数化类型的方法。
Hope this helps.
希望这可以帮助。