使用GSON解析多种类型的数组
我希望使用 GSON 解析以下 json:
[
[
"hello",
1,
[2]
],
[
"world",
3,
[2]
]
]
所以,这是 1 个数组,包含 2 个数组。 2个内部数组本身就是数组,由String、int、数组类型组成。
我不确定如何使用 Java 类来对具有 3 种不同类型(String、int、array)的数组进行建模。我开始:
// String json just contains the aforementioned json string.
ArrayList<ArrayList<XXX>> data = new ArrayList<ArrayList<XXX>>();
Type arrayListType = new TypeToken<ArrayList<ArrayList<XXX>>>(){}.getType();
data = gson.fromJson(json, arrayListType);
但是“XXX”应该在哪里?我认为它应该是一个数组,但它应该是一个具有3种不同数据类型的数组。那么我该如何使用 Java 来对此进行建模呢?
有什么可以帮忙的吗? 谢谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Gson 对将某些单组件数组反序列化为非数组类型有特殊的处理。例如,
int data = gson.fromJson("[3]", int.class);
会将 int 值 3 分配给 data。当然,不需要将单组件数组反序列化为非数组类型。例如,前面的示例可以反序列化为
int[] data = gson.fromJson("[3]", int[].class);
。当被要求时,Gson 也经常将非字符串值反序列化为字符串。将其应用于第一个示例,
String data = gson.fromJson("[3]", String.class);
也能正常工作。请注意,告诉 Gson 将第一个示例反序列化为 Object 类型是不起作用的。
Object data = gson.fromJson("[3]", Object.class);
导致解析异常,抱怨 [3] 不是原语。应用于上面原始问题中的示例,如果可以将所有值视为字符串,那么反序列化就会变得简单。
不幸的是,对于 Gson,我无法找出一种简单的反序列化方法,该方法可以“更好”地绑定到数组中更具体和混合的类型,因为 Java 不提供用于定义混合类型数组的语法。例如,原始问题中集合的首选类型可能是
List
,但这不可能在 Java 中定义。因此,您必须满足于>>
List
,或者转向更多“手动”解析的方法。> 。 (或 String[][])
(是的,Java 允许
List
的类型声明,但是>
Object
不是一个足够具体的类型,无法进行有意义的反序列化。此外,正如所讨论的,尝试将 [3] 反序列化为对象会导致解析异常。)小更新:我最近不得不反序列化一些草率的 JSON,其中包含的结构与原始问题中的结构不太相似。我最终只是使用自定义反序列化器从混乱的 JSON 数组创建一个对象。类似于下面的例子。
Gson 用户指南确实涵盖了处理混合类型集合的反序列化,其中包含类似的示例 “使用任意类型的对象序列化和反序列化集合”部分。
Gson has special handling for deserializing some single-component arrays into a non-array type. For example,
int data = gson.fromJson("[3]", int.class);
would assign the int value 3 to data.Of course, deserializing a single-component array into a non-array type is not required. For example, the previous example could be deserialized as
int[] data = gson.fromJson("[3]", int[].class);
.Gson will also often deserialize a non-String value into a String, when asked. Applying this to the first example,
String data = gson.fromJson("[3]", String.class);
works just as well.Note that it does not work to tell Gson to deserialize the first example as type Object.
Object data = gson.fromJson("[3]", Object.class);
results in a parse exception complaining that [3] is not a primitive.Applied to the example in the original question above, if it's acceptable to treat all of the values as Strings, then deserialization becomes simple.
Unfortunately, with Gson I've not been able to figure out a simple deserialization approach that would allow for "better" binding to more specific and mixed types in an array, since Java doesn't provide a syntax for defining a mixed type array. For example, the preferred type of the collection in the original question might be
List<List<String, int, List<int>>>
, but that's not possible to define in Java. So, you gotta be content withList<List<String>> (or String[][])
, or turn to an approach with more "manual" parsing.(Yes, Java allows a type declaration of
List<List<Object>>
, butObject
is not a specific enough type to meaningfully deserialize to. Also, as discussed, attempting to deserialize [3] to Object results in a parse exception.)Small Update: I recently had to deserialize some sloppy JSON that included a structure not too dissimilar from that in the original question. I ended up just using a custom deserializer to create a object from the messy JSON array. Similar to the following example.
The Gson user guide does cover handling deserialization of collections of mixed types with a similar example as this in the "Serializing and Deserializing Collection with Objects of Arbitrary Types" section.
首先,我认为你上面的例子可能是错误的。至少可以说,由三个不同的数组组成的数组是一种非常不寻常的方法。也许你的 json 结构是一个数组,包含元组。然后这些元组包含一个数组。
就像:
XXX 应该是一个包含以下内容的对象:
一个字符串
一个 int (或整数)
一个(我猜)整数的数组。
然后创建这些对象的数组并将 json 解析到其中。
但是,您的 json 看起来格式确实很糟糕,因为所有成员都应该被命名,就像
另一方面,如果 JSON 确实看起来像您描述的那样,您将必须制作简单明了的对象数组,然后进行强制转换当您从数据结构中读取它们时。
First, I think you may be mistaken in your example above. An Array consisting of three different is a very unusual approach, to say the least. Probably your json structure is an array, containing tuples. These tuples then include an array.
Like:
XXX should be an object containing:
A String
An int (or Integer)
An Array of (I guess) ints.
Then you make an array of these objects and parse the json into it.
However, your json seems really badly formed, since all members should be named, like
If, on the other hand, the JSON really looks the way you describe it, you would have to make arrays of Object, plain and simple, and then cast them when you read them from your data structure.