1

我正在使用 Genson 将我的 android 应用程序中的 json 序列化 + 反序列化为多态对象。虽然 JSON 来自多种来源,但我不能保证 @class 元数据将是 json 中的第一个行项目。遍历 Genson 代码并编写测试用例,看起来 @class 元数据必须是字典中的第一个条目。

有没有人幸运地解决了这个限制?是时候切换到其他东西了,如果是,是什么?

public class Message {
  Payload payload;
  // getters & setters
}
public abstract class Payload {
  //
}
public class Notification1 extends Payload {
  String text;
  // getters & setters
}
public class Notification2 extends Payload {
  String otherText
  // getters & setters
}

String correctOrder = {"@class":"Message","payload":{"@class":"Notification1","text":"Text"}}
String modifiedOrder = {"@class":"Message","payload":{"text":"Text", "@class":"Notification1"}}

Genson g = Genson.Builder()
            .addAlias("Notification1", Notification1.class)
            .addAlias("Notification2", Notification2.class)
            .useRuntimeType(true)
            .useClassMetadata(true)
            .useMetadata(true)
            .useFields(false)
            .useIndentation(false)
            .create();

g.deserialize(correctOrder, Message.class) // This works
g.deserialize(modifiedOrder, Message.class) // This barfs with the error: com.owlike.genson.JsonBindingException: Could not deserialize to type class com.ol.communication.messages.Message
4

1 回答 1

1

确实顺序很重要。这是故意选择的,请参阅用户指南中的备注。

如果我们允许在 json 对象中的任何位置使用 @class 属性,那么我们必须首先将所有 json 对象(及其子属性 obj/arr 等)反序列化为中间数据结构,然后再转换为正确的类型。这将导致额外的内存开销和较低的速度,但更大的灵活性,确实如此。

一个解决方案是标记多态类(构建器中的注释/配置),Genson 将在流中搜索/生成 @class 属性。这将允许仅对流中的多态对象具有此开销。

目前它没有实现,但我打开了一个问题。它将在未来的版本中出现。

在技​​术方面之外,我认为在处理多个外部 API 时不应该使用多态逻辑(或任何其他花哨的东西)。我的意思是这种功能是特定于库的,所以如果你不在双方都使用相同的工具,你可能会遇到麻烦。通常人们有一个层用于与 API 通信并将数据映射到您的模型。如果您不拥有两端的代码,我认为从长远来看这将是一个很好的解决方案。

于 2014-11-07T16:38:54.320 回答