2013-07-12 8 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); 
    }    
} 

Теперь я использую следующий наконец сделать он работает. Обратите внимание, что тип и 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[][] и т.д. тоже.

Должен ли я писать десериализатор для каждого измерения точки или есть лучший способ сделать это?

Пожалуйста, помогите.

ответ

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

Днем кодирования :)