一、簡單介紹
XStream是thoughtworks開發的開源框架,用於實現XML數據於Java對象、Json數據的轉換。它不需要schema或其他的mapping文件就可以進行java對象和xml文件之間的轉換,API調用起來非常方便,並且擴展功能強大。
1,XStream的特點
a)靈活易用:在更高的層次上提供了簡單、靈活、易用的統一接口,用戶無需瞭解項目的底層細節
b)無需映射:大多數對象都可以在無需映射的情況下進行序列化與反序列化的操作
c)高速穩定:設計時力求達到的最重要的指標是解析速度快、佔用內存少,以使之能夠適用於大的對象處理或是對信息吞吐量要求高的系統
d)清晰易懂:項目採用reflection機制得到無冗餘信息的XML文件。所生成的XML文件較本地Java序列化產物更簡潔,格式更清晰,更便於用戶閱讀
e)無需修改:完全序列化包括private和final類型在內的全部內部字段。支持非公有類和內部類,類可以沒有缺省的構造函數。
f)易於集成:通過實現特定的接口,XStream可以直接與其它任何樹型結構進行序列化與反序列化操作(而不僅僅是XML格式)
g)靈活轉換:轉換策略是可以定製的,允許用戶自定義特殊類型的對象如何以XML格式存儲。
h)錯誤處理:由於XML文本不合法而造成異常時,會提供詳細地診斷信息幫助處理問題。
2,應用場合
a)數據對象的持久化
b)數據交換
c)配置文件
3,架構分析
a)Converters(轉換器)
當XStream遇到需要轉換的對象時,它會委派給合適的轉換器實現,XStream爲通用類型提供了多種轉換器實現,包括基本數據類型、String、Collections、Arrays、null、Date,等等。
XStream提供了缺省的轉換器,當需要轉換的數據對象沒有匹配的轉換器時會使用。是通過反射機制自動完成對對象內所有字段的映射。
b)IO(輸入/輸出)
XStream是通過接口HierarchicalStramWriter和HierarchialStreamReader從底層XML數據中抽象而來的,上面的接口分別用於序列化和反序列化操作。
該特性使得XStream可以直接使用XML解析類從數據流中讀取數據,或者是直接從已經存在的結構中提取數據(比如DOM)。如果XStream所操作的 XML數據已經部分被其它XML解析類處理過了(比如SOAP類的實例),這樣就可以避免在我們這一層的再次解析操作。
c)Context(上下文引用)
在XStream序列化或反序列化對象時,它會創建兩個類MarshallingContext和UnmarshallingContext,由它們來處理數據,以及委派合適的轉換器。
XStream提供了三對上下文的缺省實現,它們之間有着細微的差別。缺省值可以通過方法XStream.setMode()來改變,需要傳遞下面參數中的一個:
i)XStream.XPATH_REFERENCES,(缺省的)通過XPath引用來標識重複的引用。這樣產生的XML具有最小的混亂性。
ii)XStream.ID_REFERENCES,使用ID引用來標識重複的引用。在一些場合,比如使用手寫XML時,這樣將會更易於操作
iii)XStream.NO_REFERENCES,這種情況將失去對圖形對象的支持,僅把對象看作爲樹型結構。重複的引用被視作兩個不同的對象,循環引用會導致異常產生。相對於上面兩種模式,這種模式速度會更快,佔用內存會更
d)Facade(統一入口)
主要類XStream用作所有項目的入口點。它將上面所提及的重要組件集成在一起,提供更簡單易用的API操作。
二、資源網址
項目主頁:
在線幫助文檔:http://xstream.codehaus.org/javadoc/index.html
lib和源碼下載:http://xstream.codehaus.org/download.html
三、注意事項:
1,XStream將Java對象序列化爲XML數據時,不關心屬性字段是否是final、private類型,也不關心是否有對應的get/set方法,更不關心你是否有一個默認的無參構造方法。
2,項目的classpath中應該有3個包:xstream-[版本].jar,xpp3-[版本].jar,xmlpull-[版本].jar。
四、使用入門示例及介紹
1,示例代碼
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.StaxDriver;
public class XStreamTest {
public static void main(String[] args) {
Person p = new Person();
p.sex = new StringBuffer("未知");
p.set("如花");
p.age = 70;
System.out.println("轉換之前的Person對象p="+p);
//這樣創建XStream實例時,上面那3個jar包必須都有
// XStream xstream = new XStream();
//這裏不需要XPP3庫了,而是使用標準的JAXP DOM解析XML
// XStream xstream = new XStream(new DomDriver());
//這裏不需要XPP3庫了但是需要你使用java 6
XStream xstream = new XStream(new StaxDriver());
String xml = xstream.toXML(p);
System.out.println("轉換生成XML字符串=="+xml);
Person p2 = (Person) xstream.fromXML(xml);
System.out.println("轉換之後的Person對象p2="+p2);
}
}
class Person{
private String name;
int age;
public StringBuffer sex;
public void set(String name){
this.name = name;
}
public String toString(){
return "{name="+name+";age="+age+";sex="+sex+"}";
}
}
運行結果:
轉換之前的Person對象p={name=如花;age=70;sex=未知}
轉換生成XML字符串==<?xml version="1.0" ?><cn.tjpu.zhw.xml.Person><name>如花</name><age>70</age><sex>未知</sex></cn.tjpu.zhw.xml.Person>
轉換之後的Person對象p2={name=如花;age=70;sex=未知}
2,創建XStream對象
a)無參構造函數,默認使用XPP3包
//這樣創建XStream實例時,上面那3個jar包必須都有
XStream xstream = new XStream();
b)有參構造函數,使用標準的JAXP DOM
//這裏不需要XPP3和xmlpull庫了,而是使用標準的JAXP DOM解析XML
XStream xstream = new XStream(new DomDriver());
c)有參構造函數,使用StAX解析XML
//這裏不需要XPP3庫了但是需要你使用java 6
XStream xstream = new XStream(new StaxDriver());
3,將Java對象轉換成爲XML字符串
String xml = xstream.toXML(p);
結果是:
<?xml version="1.0" ?> <cn.tjpu.zhw.xml.Person> <name>如花</name> <age>70</age> <sex>未知</sex> </cn.tjpu.zhw.xml.Person>
4,將XML轉換成爲Java對象
Person p2 = (Person) xstream.fromXML(xml);