简体   繁体   English

Gson反序列化一个对象数组

[英]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: 我已经能够使用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);
    }               
}

Now, I use the following at last to make it work. 现在,我最后使用以下内容使其工作。 Note that type and str are strings. 请注意,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);

Now here is the main problem. 现在这是主要问题。 I want to do this for classes Point[] , Point[][] and so on also. 我想为类Point[]Point[][]等做这个。

Will I have to write a deserializer for every dimension of Point or is there a better way to do it? 我是否必须为Point的每个维度编写反序列化器,或者有更好的方法吗?

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; 无需创建本机Java数组。 you already have a JSON array: 您已经有一个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());

    }
}

Once you register that with Gson via registerTypeAdapter , arrays of that type "just work": 通过registerTypeAdapter向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);
}

Output: 输出:

3 3

The trouble you'll run into is that you're needing to get the Class dynamically and you want an array type. 您将遇到的麻烦是,您需要动态获取Class并且需要数组类型。 You can achieve this for array types by prepending [L to the fully qualified class name: 您可以通过在[L前面加上完全限定的类名来实现此类型的数组:

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

myClass now holds Point[].class myClass现在拥有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. 它可以工作......你可以使用额外的[来表示尺寸......但是你仍然需要把它作为一个Object和强制转换等等。

Honestly, the better way to do it is via a List type with a TypeToken . 老实说,更好的方法是通过带有TypeTokenList类型。

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
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. GSon有自己的内部使用的ArrayTypeAdapter I suppose it will be used automatically when you try to deserialise an array, since the same is done for List and other collections. 我想当您尝试对数组反序列化时会自动使用它,因为List和其他集合也是如此。

Since its internal to GSon, you should usually not have to perform any actions to enable or use it. 由于它是GSon的内部组件,因此通常不必执行任何操作即可启用或使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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