如何解决在jackson中配置了原始父类型之后,动态添加新的子类型
我有一个超类from tkinter import *
from tkinter import ttk
inp = [{'Currency': 'EUR','Volume': '100','Country': 'SE'},{'Currency': 'GBR','Volume': '200',{'Currency': 'CAD','Volume': '300',{'Currency': 'EUR','Volume': '400','Country': 'DK'},]
class Application(Tk):
def __init__(self):
Tk.__init__(self)
self.title("Volume")
combofr = Frame(self)
combofr.pack(expand=True,fill=X)
self.tree = ttk.Treeview(self,show='headings')
columns = list(inp[0].keys())
self.filters = []
for col in columns:
name = 'combo_' + col
self.filters.append(name)
setattr(self,name,ttk.Combobox(combofr,values=[''] + sorted(set(x[col] for x in inp)),state="readonly"))
getattr(self,name).pack(side=LEFT,expand=True,fill=X)
getattr(self,name).bind('<<ComboboxSelected>>',self.select_from_filters)
self.tree["columns"] = columns
self.tree.pack(expand=TRUE,fill=BOTH)
for i in columns:
self.tree.column(i,anchor="w")
self.tree.heading(i,text=i,anchor="w")
for i,row in enumerate(inp):
self.tree.insert("","end",values=list(row.values()))
def select_from_filters(self,event=None):
self.tree.delete(*self.tree.get_children())
all_filter = lambda x: all(x[f.split('_')[-1]] == getattr(self,f).get() or getattr(self,f).get() == '' for f in self.filters)
for row in inp:
if all_filter(row):
self.tree.insert("",values=list(row.values()))
root = Application()
root.mainloop()
,还有另外两个继承超类Field
的类。
我想动态添加子类而不影响超类更改
Field
当字段是同一类Field的实例,而没有用于映射的className属性“ Field”时,我想以此方式使用映射
public class TestConfiguration {
private List<Field> fields;
}
当字段是子类ExtendedHierarchicalField的实例,然后将className属性“ ExtendedHierarchicalField”用于映射或通过任何其他方式映射对象时,我想以此方式使用映射
{
"fields" : [ {
"name" : "First_name","type" : {
"fieldType" : {
"name" : "string"
}
},"required" : true
}]
}
解决方法
您可以使用杰克逊注释实现相同的目的。
将您的课程定义为:
Field.java
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS,property = "className")
@JsonSubTypes({
@JsonSubTypes.Type(value = SubField1.class),@JsonSubTypes.Type(value = SubField2.class)
})
public class Field {
public String name;
}
SubField1.java
public class SubField1 extends Field {
public String subField1Property = "subField1Property value";
}
SubField2.java
public class SubField2 extends Field {
public String subField2Property = "subField2Property value";
}
TestConfiguration.java
public class TestConfiguration {
public List<Field> fields;
}
主要方法
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Field field = new Field();
field.name = "main field";
Field subField1 = new SubField1();
subField1.name = "sub field 1";
Field subField2 = new SubField2();
subField2.name = "sub field 2";
TestConfiguration testConfiguration = new TestConfiguration();
testConfiguration.fields = Arrays.asList(field,subField1,subField2);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(testConfiguration);
System.out.println(json);
}
输出:
{
"fields" : [ {
"className" : ".Field","name" : "main field"
},{
"className" : ".SubField1","name" : "sub field 1","subField1Property" : "subField1Property value"
},{
"className" : ".SubField2","name" : "sub field 2","subField2Property" : "subField2Property value"
} ]
}
注意:
-
className
属性是强制性的(即使对于顶级类Field
也是如此),原因是当您将相同的json反序列化为POJO
而没有className
属性时,这会让创建Field
,SubField1
或SubField2
的实例感到困惑。 - 为方便起见,我在
POJO
中使用了公共财产。您应该只喜欢使用setter / getter的私有字段。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。