我使用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
答案 0 :(得分:1)
确实这个命令很重要。这是故意选择的,请参阅the user guide中的评论。
如果我们在json对象中的任何地方允许@class属性,那么我们必须首先将所有json对象(及其子属性obj / arr等)反序列化为中间数据结构,然后再解析为正确的类型。 这会产生额外的内存开销和更低的速度,但更大的灵活性,确实如此。
解决方案是标记多态的类(构建器中的注释/配置),Genson将为其搜索/生成流中的@class属性。这将允许仅为流中的多态对象提供此开销。
目前尚未实施,但我打开了an issue。它将在未来发布。
在技术方面之外,当你处理多个外部API时,我认为你不应该有多态逻辑(或任何其他花哨的东西)。我的意思是这种功能是特定于库的,所以如果你不在两侧使用相同的工具,你可能会遇到麻烦。通常人们有一个层用于与API通信并将数据映射到您的模型。如果您不拥有两端的代码,我认为从长远来看这将是一个很好的解决方案。