GSON反序列化:如何知道对象?

4
我尝试使用gson库来反序列化发送给我的一系列对象。在我看到的所有例子中,当调用fromJson方法时,我们已经知道我们期望拥有哪种类型的对象。
在我的情况下,我接收到不同类型的对象流,我想知道在反序列化之前如何最好地知道这些对象的类。
{ A : {...}, B : { B1 : {...}, B2 : {...} }, C : {...} }

在这个例子中,我希望有一种方法来知道是否已经向我发送了3个对象:A.class、B.class 和 C.class。谢谢。
3个回答

6

该文档包含使用任意类或两个步骤(首先在集合中进行通用反序列化,然后进行内容反序列化)的反序列化示例。

这个例子看起来非常符合您的需求。您可以适应它以使用。

JsonObject obj = parser.parse(json).getAsJsonObject();

想要得到一个JsonObject而不是一个数组,这样你就可以迭代所有属性(使用entrySet),并根据名称反序列化(a = gson.fromJson(myjsonelement, A.class);)只需将名称映射到类即可。


谢谢,JsonArray 看起来是我需要的。我明天会试一下。谢谢。 - Antonio Lokas

3
如果json对象中有一个字段可以用于识别您需要使用的子类,则可以使用Gson on Fire:https://github.com/julman99/gson-fire。它具有称为类型选择器的功能,正好符合您的要求。假设有一个基类和两个子类A和B,则代码如下:
GsonFireBuilder builder = new GsonFireBuilder()
    .registerTypeSelector(Base.class, new TypeSelector<Base>() {
        @Override
        public Class<? extends Base> getClassForElement(JsonElement readElement) {
            String kind = readElement.getAsJsonObject().get("kind").getAsString();
            if(kind.equals("a")){
                return A.class; //This will cause Gson to deserialize the json mapping to A
            } else if(kind.equals("b")) {
                return B.class; //This will cause Gson to deserialize the json mapping to B
            } else {
                return null; //returning null will trigger Gson's default behavior
            }
        }
    });
Gson gson = builder.createGson();

2

我也遇到了这个问题。Gson无法确定字段值的实际类,它只尝试实例化用于定义该字段的类。不用说,经常会得到不符合我们期望的结果。

因此,如果你有一个

class C {
    private A a;
    private A c;
}

class B extends A {
}

在运行时,您

C c;
c.a = new B();
c.c = new B();

反序列化之后得到的是:
c.a.getClass()==A.class;
c.b.getClass()==A.class;

因此,您必须明确指定子类。这是一个包装类,可以与Gson兼容。

public class S<T> {
    private String objectClass; 
    private String rawObjectRepresentation;
    // Gson needs no args constructor
    public S() {
    }

    public S(T obj) {
        objectClass = obj.getClass().getName();
        rawObjectRepresentation = getGson().toJson(obj);
    }

    @SuppressWarnings("unchecked")
    public T extract() throws ClassNotFoundException {
        final Class<?> clazz = Class.forName(objectClass);
        return (T)getGson().fromJson(rawObjectRepresentation, clazz);
    }

    private Gson getGson() {
        return new GsonBuilder().create();
    }

    @Override
    public String toString() {
        return "type:"+objectClass;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接