2010-06-16 41 views
0

我正在尋找一種將Java對象序列化爲XML以供RESTful Web服務使用的方法。我沒有XSD。Easy XML Serializer for Java

我已經看過了以下內容:

  1. JAXB - 相當沉重的重量與上課所需的註釋和也是一個ObjectFactory類和/或jaxb.in​​dex文件

  2. 簡單 - 需要註解但沒有其他配置類/文件。不幸的是它不能序列化集合。

  3. XStream的 - 沒有註釋等要求,但不支持泛型

沒有任何人有什麼建議?

回答

1

我的投票將是XStream。支持泛型的缺乏是要付出很大的靈活性的一小部分代價。您也可以在序列化時通過序列化泛型類類型來輕鬆實現泛型,或者將其構建到域對象中。例如。

class Customer 
    { 
     List<Order> orders; 

     public List<Order> getOrders() 
     { 
     return orders; 
     } 
    } 

在流中,元素類型表示每個對象的類型。當類型是抽象類型或接口時,與實現類一起列出的元素,除非已將該元素指定爲該接口類型的默認類型。 (例如,ArrayList作爲靜態類型List實例的默認值)。

泛型是java中的「玫瑰色眼鏡」 - 它們並不真正改變你所看到的,只是你如何看待它。如果使用泛型支持發送對象,那麼這些對象將通過線路發送完全相同。

+0

如果我的投票支持泛型,我的投票也是支持XStream的,我不明白你的意思是「序列化泛型類型在序列化類型「。另外,你的例子看起來沒有什麼明顯的不同(我的集合類型是一個集合,而不是一個列表)。這是如何將序列化類型構建到對象中的? – sdoca 2010-06-16 21:50:13

+0

@sdoca - 對不起,這是一個錯字 - 我的意思是「序列化時間」。重點在於,您不需要流中的泛型,因爲實際類型是顯式存儲的,或者是隱含的 - 無論集合是否具有泛型,都會序列化相同的對象。你能舉一個XStream不能爲你做什麼的例子,我會看看我能否幫助你。 – mdma 2010-06-16 22:05:05

+0

我將我的測試類重新編碼爲使用XStream來確認我遇到的問題,即Collection元素未包含在XML中。我做了一些研究,發現一個郵件列表線程聲明它不被支持。也許那是舊的? XML看起來是否正常包含對集合元素中父對象的「引用」?例如。 <對象A參考= 「../../ ..」/> sdoca 2010-06-16 23:15:18

4
import java.beans.XMLEncoder; 
import java.beans.XMLDecoder; 
import java.io.*; 

public class XMLSerializer { 
    public static void write(Object f, String filename) throws Exception{ 
     XMLEncoder encoder = 
      new XMLEncoder(
       new BufferedOutputStream(
       new FileOutputStream(filename))); 
     encoder.writeObject(f); 
     encoder.close(); 
    } 

    public static Object read(String filename) throws Exception { 
     XMLDecoder decoder = 
      new XMLDecoder(new BufferedInputStream(
       new FileInputStream(filename))); 
     Object o = (Object)decoder.readObject(); 
     decoder.close(); 
     return o; 
    } 
} 
+0

感謝您的建議。我嘗試了它,並且XML包含描述該類的東西(例如,我不想成爲Web服務中發回的響應的一部分但是這並不是我所需要的 – sdoca 2010-06-16 21:45:39

4

JAXB非常簡單,並且附帶了Java 6,它佔用的空間很小。

您可以得到一個註釋的價格。

Order.java

package xxx; 


import java.util.Date; 
import java.util.List; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Order { 

    int custId; 
    Date orderDate; 
    String description; 
    List<Item> items; 

    public void setCustId(int custId) { 
     this.custId = custId; 
    } 

    public void setOrderDate(Date orderDate) { 
     this.orderDate = orderDate; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public void setItems(List<Item> items) { 
     this.items = items; 
    } 

    public int getCustId() { 
     return custId; 
    } 

    public Date getOrderDate() { 
     return orderDate; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public List<Item> getItems() { 
     return items; 
    } 

    public String toString() { 
     return "Order: " + custId + " - " + orderDate + " - " + description + " - " + items; 
    } 
} 

Item.java:

package xxx; 

public class Item { 

    String name; 
    private int qty; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public int getQty() { 
     return qty; 
    } 

    public void setQty(int qty) { 
     this.qty = qty; 
    } 

    public String toString() { 
     return "Item:" + name + " - " + qty; 
    } 
} 

Test.java:

package xxx; 

import java.io.StringReader; 
import java.io.StringWriter; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 

public class Test { 

    public static void main(String args[]) throws Exception { 
    Order o = new Order(); 
     o.setCustId(123); 
     o.setDescription("New order"); 
     o.setOrderDate(new Date()); 

     List<Item> items = new ArrayList<Item>(); 

     Item i = new Item(); 
     i.setName("Duck Soup"); 
     i.setQty(10); 
     items.add(i); 

     i = new Item(); 
     i.setName("Carrots"); 
     i.setQty(4); 

     items.add(i); 

     o.setItems(items); 


     //Write it 
     JAXBContext ctx = JAXBContext.newInstance(Order.class); 

     Marshaller m = ctx.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     StringWriter sw = new StringWriter(); 
     m.marshal(o, sw); 
     sw.close(); 
     System.out.println(sw.toString()); 

     // Read it back 
     JAXBContext readCtx = JAXBContext.newInstance(Order.class); 
     Unmarshaller um = readCtx.createUnmarshaller(); 

     Order newOrder = (Order) um.unmarshal(new StringReader(sw.toString())); 
     System.out.println(newOrder); 
    } 
} 

結果:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<order> 
    <custId>123</custId> 
    <description>New order</description> 
    <items> 
     <name>Duck Soup</name> 
     <qty>10</qty> 
    </items> 
    <items> 
     <name>Carrots</name> 
     <qty>4</qty> 
    </items> 
    <orderDate>2010-06-16T18:12:06.870-07:00</orderDate> 
</order> 

Order: 123 - Wed Jun 16 18:12:06 PDT 2010 - New order - [Item:Duck Soup - 10, Item:Carrots - 4] 
+0

你的例子沒有顯示需要一個ObjectFactory類和/或jaxb.in​​dex文件,如果我錯了,糾正我是強制性的。所以你不僅要註釋你的課程,你需要額外的配置。 – sdoca 2010-06-17 14:42:45

+0

這是對的,你的錯。如果需要一個ObjectFatory,那麼這個例子將不起作用,對嗎?但它確實有效,如果你真的嘗試過,並且相信我會花時間發佈一個準確的示例,並且知道我在說什麼,而不是依賴於你的先入之見,那麼你就會知道。我從來沒有在我的項目中使用這些東西。這顯示了使用默認值可以獲得的內容。對於高級案例,或許它們是必需的,但我從未需要它們用於我的項目中的自己的對象(相對於已發佈的模式)。不過,我確實使用了更多註釋。 – 2010-06-17 15:50:02

+1

當我試圖只註釋我的一個類時,我得到一個錯誤,因爲我的對象互相引用,並會導致無限循環。當我註釋每個類/屬性,我得到錯誤「線程中的異常'main'javax.xml.bind.JAXBException:'mypackage'不包含ObjectFactory.class或jaxb.in​​dex「。對不起,我提出了一個問題來冒犯你,但我與JAXB的經歷與你的不同。 – sdoca 2010-06-17 18:31:08

0

您可以嘗試JLibs XMLDocument。它使用SAX創建XML,因此輕量且具有完全控制。