我正在使用 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
最佳答案
确实顺序很重要。这是故意选择的,请参阅 the user guide 中的备注.
如果我们允许在 json 对象中的任何位置使用 @class 属性,那么我们必须首先将所有 json 对象(及其子属性 obj/arr 等)反序列化为中间数据结构,然后再反序列化为正确的类型。 这会导致额外的内存开销和较低的速度,但会带来更大的灵 active ,这是真的。
一个解决方案是标记多态的类(构建器中的注释/配置),Genson 将在流中搜索/生成@class 属性。这将允许仅对流中的多态对象产生这种开销。
目前还没有实现,但是我打开了an issue .它将在未来的版本中出现。
除了技术方面,我认为在处理多个外部 API 时不应该有多态逻辑(或任何其他花哨的东西)。我的意思是这种功能是特定于库的,所以如果你不在双方使用相同的工具,你可能会遇到麻烦。通常人们有一个层将用于与 API 通信并将数据映射到您的模型。如果您不拥有两端的代码,我认为从长远来看,这将是一个很好的解决方案。
关于java - Genson 中类元数据的顺序很重要 - 有解决方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26792641/