简体   繁体   中英

Gson deserializing an Array of Objects

I have an object

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

I have been able to deserialize this object with Gson like so:

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

Now, I use the following at last to make it work. Note that type and str are strings.

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

Now here is the main problem. I want to do this for classes Point[] , Point[][] and so on also.

Will I have to write a deserializer for every dimension of Point or is there a better way to do it?

Please help.

First off, you're really introducing a bit of un-needed overhead in your deserializer. There's no need to create the native Java array; you already have a JSON array:

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

    }
}

Once you register that with Gson via registerTypeAdapter , arrays of that type "just work":

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

Output:

3

The trouble you'll run into is that you're needing to get the Class dynamically and you want an array type. You can achieve this for array types by prepending [L to the fully qualified class name:

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

myClass now holds Point[].class

This kinda gets rather ugly in a hurry when you start talking about multiple dimensions. It works ... you can use additional [ to represent the dimensions ... but then you still need to get it back as an Object and cast, etc.

Honestly, the better way to do it is via a List type with a 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);

}

Output:

3
3

This is how to deserialize array of objects:

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

Happy coding :)

GSon has its own ArrayTypeAdapter that is used internally. I suppose it will be used automatically when you try to deserialise an array, since the same is done for List and other collections.

Since its internal to GSon, you should usually not have to perform any actions to enable or use it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM