2011-03-21 87 views
11

我希望使用GSON解析以下JSON来解析数组:使用GSON与多种类型

[ 
    [ 
     "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来建模呢?

任何帮助? 谢谢。

+0

你的JSON是_wrong_。 – Nishant 2011-03-21 14:23:41

+1

代码与我从服务器收到的代码完全相同......不幸的是,我无法更改我收到的数据。当然,这不会使JSON数据正确。 :P – Fofx 2011-03-21 15:36:04

+0

的可能的复制[GSON反序列化与多个对象类型JSON数组](https://stackoverflow.com/questions/36780871/gson-deserialize-json-array-with-multiple-object-types) – ed22 2017-09-12 03:10:12

回答

0

首先,我想你可能会误以上例。至少可以说,由三种不同的数组组成的数组是一种非常不寻常的方法。可能你的json结构是一个包含元组的数组。这些元组包含一个数组。

喜欢:

[ 
{ 
    "hello", 
    1, 
    [2] 
}, 
{ 
    "world", 
    3, 
    [2] 
} 
] 

XXX应该是包含一个对象:

的String

的int(或整数)

的(I猜)数组整数。

然后你创建一个这些对象的数组,然后解析json。

但是,您的JSON似乎真的糟糕形成的,因为所有成员应命名,像

[ 
{ 
    "str":"hello", 
    "intVal":1, 
    "intArr":[2] 
}, 
{ 
    "str":"world", 
    "intVal":3, 
    "intArr":[2] 
} 
] 

如果,另一方面,JSON真的看起来你描述的方式,你将不得不作出Object的数组,简单明了,然后在从数据结构中读取它们时将其转换。

+0

这正是我思过......如果JSON是格式为:{ “STR”: “你好”, “INTVAL”:1, “将intArr”:[2] }, 然后,我可以简单地创建我的自己的类,它模拟了这些数据。不幸的是,数据真的是因为我张贴....因此,我的问题和这篇文章:) 我会尝试你的建议,看看它是否工作。谢谢您的回复。 – Fofx 2011-03-21 15:07:45

+0

好的,我不确定这种铸造方法是否可行。你是否建议我这样做: 'ArrayList > data = new ArrayList >(); \t 类型arrayListType = new TypeToken >>(){}。getType();我知道这可能是如何工作来存储一个字符串或int,但数组中的第三项是一个数组,如果这个数组包含一个JSON对象{}那么{}然后,我们可以使用这个数组来创建一个数组,我将如何建模? – Fofx 2011-03-21 15:27:45

+0

我收到以下错误: 'com.google.gson.JsonParseException:类型信息不可用,并且目标不是原语:[2]' 因此,第3个项目出现问题...将intArr – Fofx 2011-03-21 15:33:21

13

Gson有一些特殊的处理方式来将一些单一组件数组反序列化为非数组类型。例如,int data = gson.fromJson("[3]", int.class);会将int值3分配给数据。

当然,不需要将单个组件阵列反序列化为非数组类型。例如,前面的示例可以反序列化为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]不是原语。

应用于上述原始问题的示例中,如果将所有值视为字符串都可接受,则反序列化将变得很简单。

// output: 
// hello 1 2 
// world 3 2 

public class Foo 
{ 
    static String jsonInput = 
    "[" + 
     "[\"hello\",1,[2]]," + 
     "[\"world\",3,[2]]" + 
    "]"; 

    public static void main(String[] args) 
    { 
    Gson gson = new Gson(); 
    String[][] data = gson.fromJson(jsonInput, String[][].class); 
    for (String[] data2 : data) 
    { 
     for (String data3 : data2) 
     { 
     System.out.print(data3); 
     System.out.print(" "); 
     } 
     System.out.println(); 
    } 
    } 
} 

不幸的是,我GSON已经无法找出一个简单的反序列化的办法,将允许阵列中的“更好”的结合更加具体和混合型,因为Java不提供语法用于定义混合类型的数组。例如,原始问题中收集的首选类型可能是List<List<String, int, List<int>>>,但这在Java中无法定义。所以,你必须满足于List<List<String>> (or String[][]),或者转向更“手动”解析的方法。

(是,Java允许的List<List<Object>>类型声明,但Object不是特定足够型有意义反序列化到。此外,如所讨论的,当试图反序列化[3]到对象在分析异常的结果。)


小更新:我最近不得不反序列化一些不稳定的JSON,其中包含的结构与原始问题中的结构不太相似。我结束了使用自定义的反序列化器来从杂乱的JSON数组中创建一个对象。类似于下面的例子。

// output: 
// [{MyThreeThings: first=hello, second=1, third=[2]}, 
// {MyThreeThings: first=world, second=3, third=[4, 5]}] 

import java.lang.reflect.Type; 
import java.util.Arrays; 

import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 
import com.google.gson.JsonArray; 
import com.google.gson.JsonDeserializationContext; 
import com.google.gson.JsonDeserializer; 
import com.google.gson.JsonElement; 
import com.google.gson.JsonParseException; 

public class FooToo 
{ 
    static String jsonInput = 
     "[" + 
      "[\"hello\",1,[2]]," + 
      "[\"world\",3,[4,5]]" + 
     "]"; 

    public static void main(String[] args) 
    { 
    GsonBuilder gsonBuilder = new GsonBuilder(); 
    gsonBuilder.registerTypeAdapter(MyThreeThings.class, new MyThreeThingsDeserializer()); 
    Gson gson = gsonBuilder.create(); 
    MyThreeThings[] things = gson.fromJson(jsonInput, MyThreeThings[].class); 
    System.out.println(Arrays.toString(things)); 
    } 
} 

class MyThreeThings 
{ 
    String first; 
    int second; 
    int[] third; 

    MyThreeThings(String first, int second, int[] third) 
    { 
    this.first = first; 
    this.second = second; 
    this.third = third; 
    } 

    @Override 
    public String toString() 
    { 
    return String.format(
     "{MyThreeThings: first=%s, second=%d, third=%s}", 
     first, second, Arrays.toString(third)); 
    } 
} 

class MyThreeThingsDeserializer implements JsonDeserializer<MyThreeThings> 
{ 
    @Override 
    public MyThreeThings deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 
     throws JsonParseException 
    { 
    JsonArray jsonArray = json.getAsJsonArray(); 
    String first = jsonArray.get(0).getAsString(); 
    int second = jsonArray.get(1).getAsInt(); 
    JsonArray jsonArray2 = jsonArray.get(2).getAsJsonArray(); 
    int length = jsonArray2.size(); 
    int[] third = new int[length]; 
    for (int i = 0; i < length; i++) 
    { 
     int n = jsonArray2.get(i).getAsInt(); 
     third[i] = n; 
    } 
    return new MyThreeThings(first, second, third); 
    } 
} 

的GSON用户指南确实盖处理混合类型的集合的反序列化在the "Serializing and Deserializing Collection with Objects of Arbitrary Types" section一个类似的例子,因为这。