【问题标题】:Can't serialize/deserialize classes implementing interface with GSON无法序列化/反序列化实现与 GSON 接口的类
【发布时间】:2017-05-09 19:15:32
【问题描述】:

我正在尝试序列化具有接口对象列表的类。我添加了一个应该让它工作的类型寄存器,但是我不走运,因为它仍然无法工作。代码如下。

规则:

public interface Rule extends Serializable {

    public String getName();

    public boolean setData(String data);
    public String getData();

}

规则摘要:

public abstract class RuleAbstract implements Rule {

    private static transient final long serialVersionUID = 1L;

    public RuleAbstract(){ }

}

动作规则:

public interface ActionRule extends Rule {

    public void doAction(Player player);

}

ActionRule 类之一:

public class DoCmd extends RuleAbstract implements ActionRule {

    private static transient final long serialVersionUID = 1L;

    private static DoCmd i = new DoCmd();
    public static DoCmd get() { return i; }

    private String cmd;

    public DoCmd(){

    }

    @Override
    public void doAction(Player player) {
        if(this.cmd == null) return;
        MixinCommand.get().dispatchCommand(player, this.cmd);
    }

    @Override
    public boolean setData(String data) {
        /** Must start with leading slash */
        if(!data.startsWith("/")) return false;
        this.cmd = data;
        return true;
    }

    @Override
    public String getData() {
        return this.cmd;
    }

}

最后,必须序列化和反序列化的类:

public class RuleList {

    List<Rule> rules = new ArrayList<Rule>();

}

所有这些都应该适用于我的类型适配器:

public class AdapterRule implements JsonDeserializer<Rule>, JsonSerializer<Rule> {

    private static AdapterRule i = new AdapterRule();
    public static AdapterRule get() { return i; }

    @Override
    public JsonElement serialize(Rule src, Type typeOf, JsonSerializationContext context) {
        if(src.getData() != null || src.getData() != ""){
            return new JsonPrimitive(String.format("%s %s", src.getName(), src.getData()));
        }
        return new JsonPrimitive(src.getName());
    }

    @Override
    public Rule deserialize(JsonElement src, Type typeOf, JsonDeserializationContext context) throws JsonParseException {
        String splitted[] = src.getAsJsonPrimitive().getAsString().split(" ");
        if(splitted.length == 1){
            return RuleAbstract.getRule(splitted[0]);
        } else {
            String tempData = "";
            for(String data : splitted){
                tempData = tempData + " " + data;
            }
            Rule rule = RuleAbstract.getRule(splitted[0]);
            rule.setData(tempData);
            return rule;
        }
    }

}

有人可以指出我做错了什么吗?我收到的错误:

java.lang.RuntimeException: Unable to invoke no-args constructor for interface some.package.Rule. Register an InstanceCreator with Gson for this type may fix this problem.

【问题讨论】:

  • 代码太多 + 缺少一些代码片段。异常告诉你 Gson 不能实例化接口,除非它的子类构造函数是使用InstanceCreator 注册的。如果您同时提供 JSON 和完整的异常堆栈跟踪,那就更好了。
  • @LyubomyrShaydariv 您缺少什么代码?我很确定我提供了所需的一切......我会尽快使用完整的异常堆栈跟踪对其进行编辑。另外,正如您在我提供的代码中看到的那样,我已经为 GSON 和 Rule 类添加了一个适配器,这还不足以让它工作吗?
  • 它有未声明的符号。反正。如果您可以恢复原始类型,一个示例 JSON 会给出提示,因为您必须在某处拥有它(除非 DoCmd 是唯一的实现者)。至少,你注册你的JsonDeserializer了吗?
  • @LyubomyrShaydariv 是的,反序列化器/序列化器已注册。这是完整的异常堆栈跟踪:hastebin.com/azowidiyuc.swift 我试图最终得到一个如下所示的 JSON:hastebin.com/yeduvabesu.json
  • 好吧,您似乎没有注册反序列化程序。另一点:这不是一个在同一个 JSON 对象中有重复键 DoCmd 的普通 JSON。您是生成这些 JSON 文档还是从其他地方获取它们?

标签: java json serialization gson


【解决方案1】:

GSON 反序列化器需要在被反序列化的类上使用默认构造函数,即RuleList

如果您不能提供默认构造函数,那么您需要注册一个InstanceCreator,它将为反序列化器提供一个新的 RuleList。

【讨论】:

  • Gson 在设计上完全忽略了构造函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 2020-05-04
相关资源
最近更新 更多