Gson反序列化一个对象数组

时间:2013-07-12 10:56:46

标签: java json gson

我有一个对象

public class Point{
    int x, y;

    Point(int x, int y){
        this.x = x;
        this.y = y;
    }

    public String toString(){
        String ret = "[";
        ret += Integer.toString(x);
        ret += ", ";
        ret += Integer.toString(y);
        ret += "]";
        return ret;
    }
}

我已经能够像Gson一样反序列化这个对象:

class PointDeserializer implements JsonDeserializer<Point>{
    @Override
    public Point deserialize(JsonElement json, Type typeOfT,
    JsonDeserializationContext context) throws JsonParseException {
        Gson gson = new Gson();
        int[] tmp = gson.fromJson(json, int[].class);
        int a = tmp[0];
        int b = tmp[1];
        return new Point(a,b);
    }               
}

现在,我最后使用以下内容使其工作。请注意,type和str是字符串。

Class myClass = Class.forName(type);
Class myClassDeserializer = Class.forName(type + "Deserializer");
Gson gson = new GsonBuilder().registerTypeAdapter(myClass, myClassDeserializer.newInstance()).create();
Object ret = gson.fromJson(str, myClass);

现在这是主要问题。我想对课程Point[]Point[][]等进行此操作。

我是否必须为Point的每个维度编写反序列化器,或者有更好的方法吗?

请帮忙。

3 个答案:

答案 0 :(得分:5)

首先,你真的在​​解串器中引入了一些不需要的开销。无需创建本机Java数组;你已经有了一个JSON数组:

class PointDeserializer implements JsonDeserializer<Point> {

    @Override
    public Point deserialize(JsonElement json, Type typeOfT,
        JsonDeserializationContext context) throws JsonParseException {

        JsonArray array = json.getAsJsonArray(); 
        return new Point(array.get(0).getAsInt(), array.get(1).getAsInt());

    }
}

通过registerTypeAdapter向Gson注册后,该类型的数组“正常工作”:

public static void main(String[] args)
{
    String json = "[ [1,2], [3,4] ]";

    Gson gson = new GsonBuilder().registerTypeAdapter(Point.class, 
                    new MyPointDeserializer()).create();

    Point[] mpa = gson.fromJson(json, Point[].class);        
    System.out.println(mpa[1].x);
}

输出:

  

3

您遇到的麻烦是您需要动态获取Class并且需要数组类型。您可以通过将[L添加到完全限定的类名称来实现数组类型:

Class myClass = Class.forName("[L" + "my.package.Point");

myClass现在拥有Point[].class

当你开始谈论多个方面时,这种方式会变得相当丑陋。它可以工作......您可以使用额外的[来表示维度...但是您仍然需要将其作为Object并投射等等。

老实说,更好的方法是通过带有List的{​​{1}}类型。

TypeToken

输出:

  

3
3

答案 1 :(得分:2)

这是反序列化对象数组的方法:

Gson gson = new Gson();
Type collectionType = new TypeToken<List<YourObject>>(){}.getType();
List<YourObject> yourObjectsList= gson.fromJson(jsonString, collectionType);

快乐编码:)

答案 2 :(得分:0)

GSon有自己的ArrayTypeAdapter内部使用。我想当你尝试反序列化一个数组时会自动使用它,因为List和其他集合也是如此。

由于它是GSon的内部,因此通常不必执行任何操作来启用或使用它。