2

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.

3 Answers 3

6

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

Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

0

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.

1 Comment

Can you please give some details on how to do it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.