我有一個嵌套的對象層次結構,看起來像這樣:解組列表到一個JavaFX SimpleListProperty
Profile
:含有List<Category>
Category
包含List<Script>
。它通過JavaFX SimpleListProperty公開,以便它可以通過JavaFX的數據綁定綁定。
Script
只包含簡單的值。我只是使用JAXB來編組和解組POJO。沒有涉及的數據庫或XML模式。
編組Profile
值工作正常,並生成有效的XML。但是,稍後解編相同的XML文件會導致每個Category
包含一個空的List<Script>
。這似乎是由於Category通過使用JavaFX可綁定屬性來存儲List<Script>
。
有沒有辦法讓JAXB正確反序列化成一個包含自定義對象的SimpleListProperty?
下面是一個展示相同問題的最小示例。
public class Main
{
public static void main(String[] args) throws Exception
{
Script script1 = new Script();
script1.name = "Script 1";
script1.otherData = "Script 1's data";
Script script2 = new Script();
script2.name = "Script 2";
script2.otherData = "Script 2's data";
ArrayList<Script> scriptList = new ArrayList<Script>();
scriptList.add(script1);
scriptList.add(script2);
Category category1 = new Category();
category1.name = "Category 1";
category1.setCategoryScripts(scriptList);
Category category2 = new Category();
category2.name = "Category 2";
category2.setCategoryScripts(scriptList);
Profile profile = new Profile();
profile.name = "Profile 1";
profile.categories.add(category1);
profile.categories.add(category2);
JAXBContext context = JAXBContext.newInstance(Profile.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter xml = new StringWriter();
m.marshal(profile, xml);
System.out.println(xml.toString());
Profile deserializedProfile = (Profile)context
.createUnmarshaller()
.unmarshal(new StringReader(xml.toString()));
System.out.println("Profile: " + deserializedProfile.name);
for(Category cat : deserializedProfile.categories)
{
System.out.println("Category: " + cat.name);
System.out.println("Scripts:");
for(Script s : cat.getCategoryScripts())
{
System.out.printf("\nName: %s, Data: %s", s.name, s.otherData);
}
}
}
}
@XmlRootElement
class Profile
{
@XmlElement
String name;
@XmlElementWrapper
@XmlElement
ArrayList<Category> categories = new ArrayList<Category>();
}
@XmlRootElement
class Category
{
@XmlElement
String name;
ListProperty<Script> categoryScripts = new SimpleListProperty<Script>();
@XmlElementWrapper
@XmlElement
public final List<Script> getCategoryScripts() { return categoryScripts.get(); }
public final void setCategoryScripts(List<Script> value) { categoryScripts.set(FXCollections.observableArrayList(value)); }
public ListProperty<Script> categoryScriptProperty() { return categoryScripts; }
}
@XmlRootElement
class Script
{
@XmlElement
String name;
@XmlElement
String otherData;
}
注意。我將重新提出這個問題,以便有一個更簡單,可運行的示例來演示相關問題。 〜編輯〜完成。編寫樣本似乎已經解決了這個問題 - 它似乎與使用SimpleListProperty有關。 – PingZing