2011-01-05 45 views

回答

9

如果您正在尋找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> 
10

沒有什麼特別的序列化與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序列化。

+0

我發現這不行,xstream示例運行良好 – Sara 2011-03-21 01:04:33

+0

什麼不適合你?我從工作示例代碼中提取了這個。你在TestBean中實現了getter和setter嗎?我只爲此插入了適當的評論。 – vanje 2011-03-21 13:56:52

+0

此實現適用於編碼爲JavaBeans約定的類,但對於任意用戶定義的類,必須確保XMLEncoder具有正確的PersistenceDelegates。並不是所有的類都有屬性,並且並不是所有的屬性都是可寫的 - 您的類來自JavaBeans約定,您需要付出的努力越多。 – Johansensen 2012-08-08 01:08:07

2

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並實現必要的行爲來解決這些問題。但是,如果您的類在運行時重新創建非常複雜,並且希望將其序列化,那麼您應該認真考慮重新設計它以降低其複雜性 - 這將使整個過程變得更加容易,並且會大大減少出錯的機率,因爲以及未來更容易改變和擴展。

0

我不確定爲什麼在互聯網上的這麼多例子不完整,或者只是需要一點注意才能讓它們更有用。這是一個完整的例子,可以在一個文件(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) { 
    } 
    } 
}