我正在尋找一種將Java對象序列化爲XML以供RESTful Web服務使用的方法。我沒有XSD。Easy XML Serializer for Java
我已經看過了以下內容:
JAXB - 相當沉重的重量與上課所需的註釋和也是一個ObjectFactory類和/或jaxb.index文件
簡單 - 需要註解但沒有其他配置類/文件。不幸的是它不能序列化集合。
XStream的 - 沒有註釋等要求,但不支持泛型
沒有任何人有什麼建議?
我正在尋找一種將Java對象序列化爲XML以供RESTful Web服務使用的方法。我沒有XSD。Easy XML Serializer for Java
我已經看過了以下內容:
JAXB - 相當沉重的重量與上課所需的註釋和也是一個ObjectFactory類和/或jaxb.index文件
簡單 - 需要註解但沒有其他配置類/文件。不幸的是它不能序列化集合。
XStream的 - 沒有註釋等要求,但不支持泛型
沒有任何人有什麼建議?
我的投票將是XStream。支持泛型的缺乏是要付出很大的靈活性的一小部分代價。您也可以在序列化時通過序列化泛型類類型來輕鬆實現泛型,或者將其構建到域對象中。例如。
class Customer
{
List<Order> orders;
public List<Order> getOrders()
{
return orders;
}
}
在流中,元素類型表示每個對象的類型。當類型是抽象類型或接口時,與實現類一起列出的元素,除非已將該元素指定爲該接口類型的默認類型。 (例如,ArrayList作爲靜態類型List實例的默認值)。
泛型是java中的「玫瑰色眼鏡」 - 它們並不真正改變你所看到的,只是你如何看待它。如果使用泛型支持發送對象,那麼這些對象將通過線路發送完全相同。
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;
}
}
感謝您的建議。我嘗試了它,並且XML包含描述該類的東西(例如
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]
你的例子沒有顯示需要一個ObjectFactory類和/或jaxb.index文件,如果我錯了,糾正我是強制性的。所以你不僅要註釋你的課程,你需要額外的配置。 – sdoca 2010-06-17 14:42:45
這是對的,你的錯。如果需要一個ObjectFatory,那麼這個例子將不起作用,對嗎?但它確實有效,如果你真的嘗試過,並且相信我會花時間發佈一個準確的示例,並且知道我在說什麼,而不是依賴於你的先入之見,那麼你就會知道。我從來沒有在我的項目中使用這些東西。這顯示了使用默認值可以獲得的內容。對於高級案例,或許它們是必需的,但我從未需要它們用於我的項目中的自己的對象(相對於已發佈的模式)。不過,我確實使用了更多註釋。 – 2010-06-17 15:50:02
當我試圖只註釋我的一個類時,我得到一個錯誤,因爲我的對象互相引用,並會導致無限循環。當我註釋每個類/屬性,我得到錯誤「線程中的異常'main'javax.xml.bind.JAXBException:'mypackage'不包含ObjectFactory.class或jaxb.index「。對不起,我提出了一個問題來冒犯你,但我與JAXB的經歷與你的不同。 – sdoca 2010-06-17 18:31:08
您可以嘗試JLibs XMLDocument。它使用SAX創建XML,因此輕量且具有完全控制。
如果我的投票支持泛型,我的投票也是支持XStream的,我不明白你的意思是「序列化泛型類型在序列化類型「。另外,你的例子看起來沒有什麼明顯的不同(我的集合類型是一個集合,而不是一個列表)。這是如何將序列化類型構建到對象中的? – sdoca 2010-06-16 21:50:13
@sdoca - 對不起,這是一個錯字 - 我的意思是「序列化時間」。重點在於,您不需要流中的泛型,因爲實際類型是顯式存儲的,或者是隱含的 - 無論集合是否具有泛型,都會序列化相同的對象。你能舉一個XStream不能爲你做什麼的例子,我會看看我能否幫助你。 – mdma 2010-06-16 22:05:05
我將我的測試類重新編碼爲使用XStream來確認我遇到的問題,即Collection元素未包含在XML中。我做了一些研究,發現一個郵件列表線程聲明它不被支持。也許那是舊的? XML看起來是否正常包含對集合元素中父對象的「引用」?例如。 <對象A參考= 「../../ ..」/> –
sdoca
2010-06-16 23:15:18