原语领域列表的 Gson 反序列化

Gson deserialization for Realm list of primitives

我正在使用带有 gson 的领域。我有一个模式,其中有一个 int 类型字段列表。领域目前不支持原语列表。为了解决这个问题,有一个解决方案。我创建了我的 RealmInt class.

import io.realm.RealmObject;

public class RealmInt extends RealmObject {
    private int val;

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }
}

我有一个类似的大模态对象..

public class Product extends RealmObject {
    @PrimaryKey
    private int productID;
    private int priority;
    private boolean isFavourite;
    .....
    .....
    .....
    private RealmList<Document> documents;
    private RealmList<ProductInfoGroup> productInfoGroups;
    private RealmList<RealmInt> categories;

我必须将下面的 json 数组反序列化为产品模态。

[{
        "productID": 776,
        "categories": [
            35
        ],
        "name": "",
        "priority": 3,
        ......
        "status": 2,
        "documents": [
            {
                "documentID": 74,
                "productID": 776,
                "name": null,
                ....
                "isDefault": true
            }
        ],
        "productInfoGroups": [
            {
                "productInfoGroupID": 1575,
                "productID": 776,
                .....
                "productInfos": [
                    {
                        "productInfoID": 2707,
                        "productInfoGroupID": 1575,
                        "title": "",
                        ...
                    },
                    {
                        "productInfoID": 2708,
                        "productInfoGroupID": 1575,
                        ...
                    },
                    {
                        "productInfoID": 2709,
                        .....
                    }
                ]
            }
        ],
        "lastUpdateDate": 130644319676570000,
        "isActive": true
    },....]

有一个解决方案,但不适用于大对象。我只需要更改类别数组,其他反序列化必须默认完成 gson 反序列化。

您必须为不同于 JSON 表示的每个变量指定自定义类型适配器。所有其他对象都是自动处理的。在您的情况下,它只是 categories 变量,因为其余变量应该自动映射。

JSON:

[
    { "name"  : "Foo",
      "ints" : [1, 2, 3]
    },
    { "name"  : "Bar",
      "ints" : []
    }
]  

型号类:

public class RealmInt extends RealmObject {
    private int val;

    public RealmInt() {
    }

    public RealmInt(int val) {
        this.val = val;
    }

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }
}

public class Product extends RealmObject {

    private String name;
    private RealmList<RealmInt> ints;

    // Getters and setters
}

GSON配置:

Gson gson = new GsonBuilder()
        .setExclusionStrategies(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return f.getDeclaringClass().equals(RealmObject.class);
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return false;
            }
        })
        .registerTypeAdapter(new TypeToken<RealmList<RealmInt>>() {}.getType(), new TypeAdapter<RealmList<RealmInt>>() {

            @Override
            public void write(JsonWriter out, RealmList<RealmInt> value) throws IOException {
                // Ignore
            }

            @Override
            public RealmList<RealmInt> read(JsonReader in) throws IOException {
                RealmList<RealmInt> list = new RealmList<RealmInt>();
                in.beginArray();
                while (in.hasNext()) {
                    list.add(new RealmInt(in.nextInt()));
                }
                in.endArray();
                return list;
            }
        })
        .create();

JsonElement json = new JsonParser().parse(new InputStreamReader(stream));
List<Product> cities = gson.fromJson(json, new TypeToken<List<Product>>(){}.getType());

如果你有多个像 RealmInt 这样的包装变量,你需要为每个变量定义一个 TypeAdapter。另请注意,上面的 TypeAdapter 期望始终遇到数组。如果您 JSON 可能会发送 null 而不是 [] 您将需要在 TypeAdapter 中对其进行额外检查。