当前位置: 首页 > 知识库问答 >
问题:

GSON和InstanceCreator问题

陈知
2023-03-14

我有以下POJO:

public interface Shape {
    public double calcArea();
    public double calcPerimeter();
}

public class Rectangle implement Shape {
    // Various properties of a rectangle
}

public class Circle implements Shape {
    // Various properties of a circle
}

public class ShapeHolder {
    private List<Shape> shapes;

    // other stuff
}

我可以让GSON将ShapeHolder的实例序列化到JSON。但是当我试图将JSON的字符串反序列化回ShapeHolder实例时,我得到错误:

String shapeHolderAsStr = getString();
ShapeHolder holder = gson.fromJson(shapeHodlderAsStr, ShapeHolder.class);

抛出:

Exception in thread "main" java.lang.RuntimeException: Unable to invoke no-args constructor for interface    
net.myapp.Shape. Register an InstanceCreator with Gson for this type may fix this problem.
    at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:167)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162)
    ... rest of stack trace ommitted for brevity

所以我看了这里,开始实现我自己的ShapeInstanceCreator

public class ShapeInstanceCreator implements InstanceCreator<Shape> {
    @Override
    public Shape createInstance(Type type) {
        // TODO: ???
        return null;
    }
}

但现在我被困住了:我只得到了一个java。朗,反思一下。键入,但我真的需要一个java。lang.Object这样我就可以编写如下代码:

public class ShapeInstanceCreator implements InstanceCreator<Shape> {
    @Override
    public Shape createInstance(Type type) {
        Object obj = convertTypeToObject(type);

        if(obj instanceof Rectangle) {
            Rectangle r = (Rectangle)obj;
            return r;
        } else {
            Circle c = (Circle)obj;
            return c;
        }

        return null;
    }
}

我能做什么?

根据@raffian的建议(他/她发布的链接),我实现了一个interfacedapter,与链接中的完全相同(我没有做任何更改)。现在我得到了以下例外:

Exception in thread "main" com.google.gson.JsonParseException: no 'type' member found in what was expected to be an interface wrapper
    at net.myapp.InterfaceAdapter.get(InterfaceAdapter.java:39)
    at net.myapp.InterfaceAdapter.deserialize(InterfaceAdapter.java:23)

有什么想法吗?

共有2个答案

洪俊拔
2023-03-14

请注意,FlexJSON正在添加类名作为json的一部分,如下面的序列化时间。

{
    "HTTPStatus": "OK",
    "class": "com.XXX.YYY.HTTPViewResponse",
    "code": null,
    "outputContext": {
        "class": "com.XXX.YYY.ZZZ.OutputSuccessContext",
        "eligible": true
    }
}

所以JSON会很麻烦;但您不需要编写GSON所需的InstanceCreator

夹谷腾
2023-03-14

你看过这个吗?看起来是一种实现InstanceCreators的干净方法。

我也在使用Gson,但由于序列化问题,我改用了FlexJSON。使用Flex,您不需要实例创建者,只要确保您的对象具有基于JavaBean规范的所有字段的getter/setter,就可以了:

 ShapeHolder sh = new ShapeHolder();
 sh.addShape(new Rectangle());
 sh.addShape(new Circle());
 JSONSerializer ser = new JSONSerializer();
 String json = ser.deepSerialize(sh);
 JSONDeserializer<ShapeHolder> der = new JSONDeserializer<ShapeHolder>();
 ShapeHolder sh2 = der.deserialize(json);
 类似资料:
  • 问题内容: 我可以使用Gson正确地使用代码1保存到json字符串,但是当我尝试使用代码2从json字符串恢复对象时出现错误。我搜索了一些资源,似乎我需要注册InstanceCreator。 如何用Kotlin 写一个注册码?谢谢! 错误 代码1 代码2 我的课 添加 我使用后,我能得到正确的结果,当我用,为什么呢? 问题答案: Gson很难像您一样反序列化多态对象。这是您需要做的: 将Runti

  • 我可以使用代码1将正确地保存到使用Gson的json字符串中,但是当我尝试用代码2从json字符串中还原对象时,我遇到了错误。我已经搜索了一些资源,似乎我需要注册一个InstanceCreator。 我如何用Kotlin编写一个register an代码?谢谢! 错误 添加 在我使用之后,我使用时可以得到正确的结果,为什么?

  • 我陷入了一个问题,需要在反序列化过程中使用和将解析对象的引用设置为其子对象。 为了描述这个问题,下面是类结构的简单表示。 通过这种结构,我可以通过向我的 提供 来在 中设置,例如: 我知道,我可以添加额外的到我的,但我不知道如何提供我的对象的引用,该对象正在被解析(即时)到对象? 任何帮助将不胜感激!

  • 问题内容: 我有一个名为的类,该类具有一个作为参数的构造函数: 具有以下属性: 并且是我的应用程序的其他类,并具有以下构造函数: ,并且是的子类。 我想用Gson 反序列化数组,所以我写道: 以定义为: 调试时,实例具有正确的“ MainActivity”作为上下文,而其成员变量的上下文为null。 Gson 使用正确的构造函数创建了对象,但使用默认的无参数构造函数创建了实例。我怎样才能解决这个问

  • 问题内容: 我被困在我需要我的对象的设定参考使用反序列化过程中被解析到其子对象的问题和。 为了描述这个问题,下面是类结构的简单表示。 通过这样的结构,我能够设置在通过提供给我的,例如: 我知道,我可以添加额外的给我,但我不知道如何提供我的参考对象,它是在被解析(上即时)的进程对象? 任何帮助,将不胜感激! 问题答案: 您绝对应该使用GraphAdapterBuilder。 正如您在@Braj的回答

  • 我有一个名为PageItem的类,它有一个构造函数,该构造函数将上下文作为参数: 具有以下属性: 新闻提供者(Newsprovider)和主题(Topic)是我的应用程序的其他类,具有以下构造函数: