我只是想知道如何使用XMLEncoder
來序列化ArrayList<foo>
foo是我自己創建的類。用於序列化的java中的XMLEncoder
我是否需要特別做任何事情,即先定義我自己的xml結構,然後在列表中的每個值上調用toString並寫出它?
任何人都可以指點我一個很好的教程嗎? http://java.sun.com/products/jfc/tsc/articles/persistence4/這就是我一直在看,但它似乎沒有提到如何處理非庫類。
感謝
我只是想知道如何使用XMLEncoder
來序列化ArrayList<foo>
foo是我自己創建的類。用於序列化的java中的XMLEncoder
我是否需要特別做任何事情,即先定義我自己的xml結構,然後在列表中的每個值上調用toString並寫出它?
任何人都可以指點我一個很好的教程嗎? http://java.sun.com/products/jfc/tsc/articles/persistence4/這就是我一直在看,但它似乎沒有提到如何處理非庫類。
感謝
如果您正在尋找XML序列化,我建議你去XStream
Person joe = new Person("Joe", "Walnes");
joe.setPhone(new PhoneNumber(123, "1234-456"));
joe.setFax(new PhoneNumber(123, "9999-999"));
String xml = xstream.toXML(joe);
<person>
<firstname>Joe</firstname>
<lastname>Walnes</lastname>
<phone>
<code>123</code>
<number>1234-456</number>
</phone>
<fax>
<code>123</code>
<number>9999-999</number>
</fax>
</person>
沒有什麼特別的序列化與XMLEncoder一個ArrayList。
下面是一個例子:
有一個bean類testBean這個:
public class TestBean {
private String name;
private int age;
public TestBean() {
this.name = "";
this.age = 0;
}
public TestBean(String name, int age) {
this.name = name;
this.age = age;
}
// Getter and setter ...
@Override
public String toString() {
return String.format("[TestBean: name='%s', age=%d]", name, age);
}
}
和A類主其序列化ArrayList<TestBean>
並再次閱讀:
public class Main {
private static final String FILENAME = "testbeanlist.xml";
public static void main(String[] args) {
try {
// Create a list of TestBean objects ...
final List<TestBean> list = new ArrayList<TestBean>();
list.add(new TestBean("Henry", 42));
list.add(new TestBean("Tom", 11));
System.out.println("Writing list to file " + FILENAME + ": " + list);
// ... and serialize it via XMLEncoder to file testbeanlist.xml
final XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(
new FileOutputStream(FILENAME)));
encoder.writeObject(list);
encoder.close();
// Use XMLDecoder to read the same XML file in.
final XMLDecoder decoder = new XMLDecoder(new FileInputStream(FILENAME));
final List<TestBean> listFromFile = (List<TestBean>) decoder.readObject();
decoder.close();
System.out.println("Reading list: " + listFromFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
然後輸出是:
Writing list to file testbeanlist.xml: [[TestBean: name='Henry', age=42], [TestBean: name='Tom', age=11]]
Reading list: [[TestBean: name='Henry', age=42], [TestBean: name='Tom', age=11]]
TestBean
中的toString()
方法僅用於漂亮打印。它不影響XML序列化。
XMLEncoder可以用於任何類,包括用戶定義的類 - 您提到的文章詳細說明了如何執行此操作,但是它不是很好編寫,因此可能有點難以理解。
如果您的用戶定義的類遵循JavaBeans spec,那麼您可以使用encoder.writeObject()
來序列化一個List<Foo>
實例。這是因爲XML輸出只是一系列關於如何在運行時重新創建給定實例的說明。默認的PersistenceDelegate知道如何序列化一個List結構,但只有未知類的默認行爲。默認情況下,它會嘗試通過調用其nullary(無參數)構造函數來重新創建給定的對象實例,然後將其屬性逐個設置爲給定實例的值 - 如果該類是JavaBean,則保證可以實現該值。
如果你的類有一些屬性是隻讀的,即它們是由構造函數設置的,並且在構造時間之後不能更改,那麼你必須做更多的工作才能使它工作。您可以創建一個DefaultPersistenceDelegate自定義實例來識別您的類,並知道如何將適當的數據傳遞給它的構造函數,您只需將該屬性的名稱作爲列表傳遞給它,剩下的就可以完成:
PersistenceDelegate fooDelegate = new DefaultPersistenceDelegate(new String[] {"propertyName1", "propertyName2"});
encoder.setPersistenceDelegate(Foo.class, fooDelegate);
如果您的類具有不直接映射到具有getter方法的屬性的構造函數參數,並且/或者還有其他複雜性來恢復對象狀態,則通常可以通過擴展PersistenceDelegate並實現必要的行爲來解決這些問題。但是,如果您的類在運行時重新創建非常複雜,並且希望將其序列化,那麼您應該認真考慮重新設計它以降低其複雜性 - 這將使整個過程變得更加容易,並且會大大減少出錯的機率,因爲以及未來更容易改變和擴展。
我不確定爲什麼在互聯網上的這麼多例子不完整,或者只是需要一點注意才能讓它們更有用。這是一個完整的例子,可以在一個文件(PersonBean.java)中實現,它的工作原理!
// This example creates two PersonBeans, creates an ArrayList, adds the beans to the
// list, serializes the ArrayList to an XML file.
// It then loads from the XML file into a new ArrayList
//
// Keywords: ArrayList, Serialize, XMLEncode, XMLDecode
// Note: Change the XML file while the 10 second Thread.sleep is waiting to see that
// the data is actually loaded from the file.
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.beans.XMLEncoder;
import java.beans.XMLDecoder;
import java.util.ArrayList;
public class PersonBean {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return String.format("[PersonBean: name='%s', age=%d]", name, age);
}
public static void main(String[] args) {
PersonBean person1 = new PersonBean();
person1.setName("Joe");
person1.setAge(30);
PersonBean person2 = new PersonBean();
person2.setName("Jane");
person2.setAge(25);
ArrayList arrayList1 = new ArrayList();
arrayList1.add(person1);
arrayList1.add(person2);
try {
System.out.println("List 'arrayList1' = '" + arrayList1 + "'");
FileOutputStream outputStream = new FileOutputStream("PersonBean.xml");
XMLEncoder encoder = new XMLEncoder(outputStream);
encoder.writeObject(arrayList1);
encoder.close();
Thread.sleep(10000);
} catch (Exception ex) {
}
try {
FileInputStream inputStream = new FileInputStream("PersonBean.xml");
XMLDecoder decoder = new XMLDecoder(inputStream);
ArrayList<PersonBean> arrayList2 = (ArrayList<PersonBean>) decoder.readObject();
decoder.close();
System.out.println("List 'arrayList2' = '" + arrayList2 + "'");
} catch (Exception ex) {
}
}
}
我發現這不行,xstream示例運行良好 – Sara 2011-03-21 01:04:33
什麼不適合你?我從工作示例代碼中提取了這個。你在TestBean中實現了getter和setter嗎?我只爲此插入了適當的評論。 – vanje 2011-03-21 13:56:52
此實現適用於編碼爲JavaBeans約定的類,但對於任意用戶定義的類,必須確保XMLEncoder具有正確的PersistenceDelegates。並不是所有的類都有屬性,並且並不是所有的屬性都是可寫的 - 您的類來自JavaBeans約定,您需要付出的努力越多。 – Johansensen 2012-08-08 01:08:07