2013-07-12 256 views
2

我有一个对象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的每个维度写一个反序列化器吗?还是有更好的方法来实现?

请帮忙。

回答

0

GSon拥有自己的ArrayTypeAdapter,在内部使用。我想它会在你试图对一个数组进行反序列化时自动使用,因为List和其他集合也是这样。

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

+0

能否请您给一些 有关如何做的细节? – Rishi

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()); 

    } 
} 

一旦你注册与GSON通过registerTypeAdapter,对该类型的数组 “只是工作”:

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); 
} 

输出:

您遇到的麻烦是您需要获得Class动态和你想要的数组类型。您可以通过预先[L到完全合格的类名实现这个数组类型:

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

myClass现在持有Point[].class

这有点变得比较难看的,当你开始谈论多个维度着急。它的工作原理...您可以使用额外的[代表的尺寸......但你仍然需要把它找回来为Object和演员表等

老实说,更好的方式来做到这一点是通过List输入TypeToken

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][0].x); 

    Type listType = new TypeToken<ArrayList<ArrayList<Point>>>(){}.getType(); 

    List<List<Point>> list = gson.fromJson(json, listType); 

    System.out.println(list.get(1).get(0).x); 

} 

输出:

2

这是如何反序列化对象的数组:

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

编码愉快:)