一花一四季,一頁一江湖

          停不下的腳步,伴著Java成長!

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            3 Posts :: 2 Stories :: 2 Comments :: 0 Trackbacks

             

          開源項(xiàng)目Xstream簡介

           目錄

          項(xiàng)目簡介... 4

          典型的應(yīng)用場合... 5

          系統(tǒng)架構(gòu)分析... 5

          實(shí)例講解... 6

          創(chuàng)建需要序列化的對(duì)象類... 6

          初始化XStream... 9

          注冊(cè)需要轉(zhuǎn)換的類的別名... 10

          將對(duì)象序列化為XML文檔... 10

          XML文件反序列化成對(duì)象... 11

          結(jié)束語... 11

          參考資料... 11

           

            

          項(xiàng)目簡介

          開源項(xiàng)目XStream是一套簡單實(shí)用的類庫,用于序列化對(duì)象與XML對(duì)象之間的相互轉(zhuǎn)換。本文以XStream 1.1.2版進(jìn)行說明,它具有以下幾個(gè)特點(diǎn):

          ?         靈活易用:在更高的層次上提供了簡單、靈活、易用的統(tǒng)一接口,用戶無需了解項(xiàng)目的底層細(xì)節(jié)

          ?         無需映射:大多數(shù)對(duì)象都可以在無需映射的情況下進(jìn)行序列化與反序列化的操作

          ?         高速穩(wěn)定:設(shè)計(jì)時(shí)力求達(dá)到的最重要的指標(biāo)是解析速度快、占用內(nèi)存少,以使之能夠適用于大的對(duì)象處理或是對(duì)信息吞吐量要求高的系統(tǒng)

          ?         清晰易懂:項(xiàng)目采用reflection機(jī)制得到無冗余信息的XML文件。所生成的XML文件較本地Java序列化產(chǎn)物更簡潔,格式更清晰,更便于用戶閱讀

          ?         無需修改:完全序列化包括privatefinal類型在內(nèi)的全部內(nèi)部字段。支持非公有類和內(nèi)部類,類可以沒有缺省的構(gòu)造函數(shù)

          ?         易于集成:通過實(shí)現(xiàn)特定的接口,XStream可以直接與其它任何樹型結(jié)構(gòu)進(jìn)行序列化與反序列化操作(而不僅僅是XML格式)

          ?         靈活轉(zhuǎn)換:轉(zhuǎn)換策略是可以定制的,允許用戶自定義特殊類型的對(duì)象如何以XML格式存儲(chǔ)。

          ?         錯(cuò)誤處理:由于XML資料不合法而造成異常時(shí),會(huì)提供詳細(xì)地診斷信息幫助處理問題。

          典型的應(yīng)用場合

              XStream主要應(yīng)用于以下場合:

          ü         數(shù)據(jù)對(duì)象的持久化

          ü         數(shù)據(jù)交換

          ü         配置文件

          XStream系統(tǒng)架構(gòu)分析

          XStream的架構(gòu)主要由四部分組成:

          2        Converters(轉(zhuǎn)換器)

              當(dāng)XStream遇到需要輪換的對(duì)象時(shí),它會(huì)委派給合適的轉(zhuǎn)換器實(shí)現(xiàn),XStream為通用類型提供了多種轉(zhuǎn)換器實(shí)現(xiàn),包括基本數(shù)據(jù)類型、StringCollectionsArraysnullDate,等等。

              XStream提供了缺省的轉(zhuǎn)換器,當(dāng)需要轉(zhuǎn)換的數(shù)據(jù)對(duì)象沒有匹配的轉(zhuǎn)換器時(shí)會(huì)使用。是通過反射機(jī)制自動(dòng)完成對(duì)對(duì)象內(nèi)所有字段的映射。

          2        IO(輸入/輸出)

              XStream是通過接口HierarchicalStramWriterHierarchialStreamReader從底層XML數(shù)據(jù)中抽象而來的,上面的接口分別用于序列化和反序列化操作。

          該特性使得XStream可以直接使用XML解析類從數(shù)據(jù)流中讀取數(shù)據(jù),或者是直接從已經(jīng)存在的結(jié)構(gòu)中提取數(shù)據(jù)(比如DOM)。如果XStream所操作的XML數(shù)據(jù)已經(jīng)部分被其它XML解析類處理過了(比如SOAP類的實(shí)例),這樣就可以避免在我們這一層的再次解析操作。

          2        Context(上下文引用)

          XStream序列化或反序列化對(duì)象時(shí),它會(huì)創(chuàng)建兩個(gè)類MarshallingContextUnmarshallingContext,由它們來處理數(shù)據(jù),以及委派合適的轉(zhuǎn)換器。

          XStream提供了三對(duì)上下文的缺省實(shí)現(xiàn),它們之間有著細(xì)微的差別。缺省值可以通過方法XStream.setMode()來改變,需要傳遞下面參數(shù)中的一個(gè):

          ?         XStream.XPATH_REFERENCES

          (缺省的)通過XPath引用來標(biāo)識(shí)重復(fù)的引用。這樣產(chǎn)生的XML具有最小的混亂性。

          ?         XStream.ID_REFERENCES

          使用ID引用來標(biāo)識(shí)重復(fù)的引用。在一些場合,比如使用手寫XML時(shí),這樣將會(huì)更易于操作

          ?         XStream.NO_REFERENCES

          這種情況將失去對(duì)圖形對(duì)象的支持,僅把對(duì)象看作為樹型結(jié)構(gòu)。重復(fù)的引用被視作兩個(gè)不同的對(duì)象,循環(huán)引用會(huì)導(dǎo)致異常產(chǎn)生。相對(duì)于上面兩種模式,這種模式速度會(huì)更快,占用內(nèi)存會(huì)更少。

          2        Facade(統(tǒng)一入口)

              主要類XStream用作所有項(xiàng)目的入口點(diǎn)。它將上面所提及的重要組件集成在一起,提供更簡單易用的API操作。

          實(shí)例講解

          下面我們通過一個(gè)簡單的例子來了解XStream是如何工作的。

          創(chuàng)建需要序列化的對(duì)象類

          /**個(gè)人信息類*/

          public class Person

          {

          /**

           * 構(gòu)造函數(shù)

               * @param fn 名稱前部分

               * @param ln名稱后部分

               * @param faxn 傳真號(hào)碼

               * @param mobilen 移動(dòng)電話

               */

              public Person(String fn, String ln, PhoneNumber faxn, PhoneNumber mobilen)

              {

                  this.firstName = fn;

                  this.lastName = ln;

                  this.faxNumber = faxn;

                  this.mobileNumber = mobilen;

              }

           

          /**

           * 構(gòu)造函數(shù)

               * @param fn 名稱前部分

               * @param ln名稱后部分

               */

              public Person(String fn, String ln)

              {

                  this.firstName = fn;

                  this.lastName = ln;

              }

           

              private String firstName;

           

              private String lastName;

           

              private PhoneNumber faxNumber;

           

              private PhoneNumber mobileNumber;

           

              /**

               * @return Returns the faxNumber.

               */

              public PhoneNumber getFaxNumber()

              {

                  return faxNumber;

              }

           

              /**

               * @param faxNumber

               * The faxNumber to set.

               */

              public void setFaxNumber(PhoneNumber faxNumber)

              {

                  this.faxNumber = faxNumber;

              }

           

              /**

               * @return Returns the firstName.

               */

              public String getFirstName()

              {

                  return firstName;

              }

           

              /**

               * @param firstName

               * The firstName to set.

               */

              public void setFirstName(String firstName)

              {

                  this.firstName = firstName;

              }

           

              /**

               * @return Returns the lastName.

               */

              public String getLastName()

              {

                  return lastName;

              }

           

              /**

               * @param lastName

               * The lastName to set.

               */

              public void setLastName(String lastName)

              {

                  this.lastName = lastName;

              }

           

              /**

               * @return Returns the mobileNumber.

               */

              public PhoneNumber getMobileNumber()

              {

                  return mobileNumber;

              }

           

              /**

               * @param mobileNumber

               * The mobileNumber to set.

               */

              public void setMobileNumber(PhoneNumber mobileNumber)

              {

                  this.mobileNumber = mobileNumber;

              }

          }

           

          /**電話號(hào)碼信息類*/

          public class PhoneNumber

          {

              private int phoneId;

           

              private String phoneNumber;

           

          /**

           * 構(gòu)造函數(shù)

               * @param phoneId ID號(hào)碼

               * @param phoneNumber 電話號(hào)碼

               */

              public PhoneNumber(int phoneId, String phoneNumber)

              {

                  super();

                  this.phoneId = phoneId;

                  this.phoneNumber = phoneNumber;

              }

           

              /**

               * @return Returns the phoneNumber.

               */

              public String getPhoneNumber()

              {

                  return phoneNumber;

              }

           

              /**

               * @param phoneNumber

               * The phoneNumber to set.

               */

              public void setPhoneNumber(String phoneNumber)

              {

                  this.phoneNumber = phoneNumber;

          }

           

              /**

               * @return Returns the phoneId.

               */

              public int getPhoneId()

              {

                  return phoneId;

              }

           

              /**

               * @param phoneId

               * The phoneId to set.

               */

              public void setPhoneId(int phoneId)

              {

                  this.phoneId = phoneId;

              }

          }

          這里定義的屬性都為privateXStream沒有強(qiáng)制規(guī)定屬性的可見性,默認(rèn)情況下所有屬性都會(huì)進(jìn)行轉(zhuǎn)換;雖然XStream不強(qiáng)制要求你必須要有settergetter方法,也不要求你要有一個(gè)默認(rèn)的類構(gòu)造方法,但是在實(shí)際應(yīng)用時(shí),這些還是必須的,因?yàn)槟阍诔绦蛑行枰獮閷?duì)象設(shè)置屬性,需要構(gòu)造對(duì)象,如果沒有這些方法程序是不能編譯通過的。

          初始化XStream

          使用以下的語句進(jìn)行初始化操作:

          XStream xstream = new XStream();

          默認(rèn)情況下,XStream會(huì)采用Xpp3庫,XPP3是一種運(yùn)行效率非常高的XML全解析實(shí)現(xiàn)。如果你不想依靠Xpp3庫的話,也可以使用一個(gè)標(biāo)準(zhǔn)的JAXP DOM解析器,可以采用以下語句進(jìn)行初始化:

          //不使用XPP3

          XStream xstream = new XStream(new DomDriver());

          xstream實(shí)例,為線程安全的,可以供多個(gè)線程進(jìn)行調(diào)用,共享使用。參考com.thoughtworks.xstream.io.xml包,會(huì)發(fā)現(xiàn)系統(tǒng)提供了多種標(biāo)識(shí)解析器供我們選擇,包括,DomDriverJDomDriverStaxDriver等等。

          注冊(cè)需要轉(zhuǎn)換的類的別名

          現(xiàn)在,為了使XStream輸出的XML文件更簡練,我們要為需要轉(zhuǎn)換的用戶類設(shè)置別名,這些明會(huì)在轉(zhuǎn)換過程中用于結(jié)點(diǎn)設(shè)置,注冊(cè)別名使用以下的語句:

          xstream.alias(“person”, Person.class);

          xstream.alias(“phonenumber”, PhoneNumber.class);

          當(dāng)然,這一步不是必須的,如果不進(jìn)行注冊(cè)的話,XStream默認(rèn)會(huì)在轉(zhuǎn)換時(shí),將用戶類的全限定名稱加入到XML文件中,如com.test.Person,如果在數(shù)據(jù)量較大的時(shí)候,生成的XML文件會(huì)增大不少。

          將對(duì)象序列化為XML文檔

              到了這一步,我們就可以將一個(gè)Java對(duì)象序列化為XML文檔了,先聲明一個(gè)Person對(duì)象,然后為該對(duì)象設(shè)置一個(gè)手機(jī)號(hào)碼,一個(gè)傳真號(hào)碼,使用下面的語句:

          //生成Person對(duì)象,并注冊(cè)屬性

          Person joe = new Person("Bill", "Gates");

          joe.setFaxNumber(new PhoneNumber(101, "83501194"));

          joe.setMobileNumber(new PhoneNumber(102, "13686447788"));

              下面就是將生成的對(duì)象序列化,我們需要做的只是簡單的使用下面的一個(gè)語句就可以:

          String xmls = xstream.toXML(joe);

              從結(jié)果我們可以看出,生成的XML文件非常簡潔,除了必要的結(jié)點(diǎn)外,沒有一絲多余的信息存在。參考下面的生成結(jié)果:

          <person>

            <firstName>Bill</firstName>

            <lastName>Gates</lastName>

            <faxNumber>

              <phoneId>101</phoneId>

              <phoneNumber>83501194</phoneNumber>

            </faxNumber>

            <mobileNumber>

              <phoneId>102</phoneId>

              <phoneNumber>13686447788</phoneNumber>

            </mobileNumber>

          </person>

          XML文件反序列化成對(duì)象

                 從一個(gè)XML文件反序列化出一個(gè)對(duì)象同樣簡單,一起來看下面的代碼:

          Person newJoe = (Person)xstream.fromXML(xmls);

          結(jié)束語

                 通過上面的實(shí)例,我們可以看出,使用XStream來處理對(duì)象的序列化和反序列化很簡單,只需要幾行代碼即可,而且該項(xiàng)目對(duì)標(biāo)識(shí)的XML解析器有很好的支持,最重要的是生成的XML很“干凈”,沒有過多的冗余信息,該項(xiàng)目還在持續(xù)進(jìn)行中,讓我們一起來關(guān)注它吧!

          參考資料

          l         XStream官方資料 http://xstream.codehaus.org/index.html

          l         本例相關(guān)代碼(附件)

          posted on 2006-02-16 13:17 魔戒 閱讀(695) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 海淀区| 成安县| 迁西县| 景洪市| 安岳县| 孝昌县| 新平| 醴陵市| 沾化县| 凤山市| 平南县| 平罗县| 道真| 乌兰浩特市| 松阳县| 将乐县| 星子县| 阜阳市| 富源县| 周宁县| 万年县| 新乡市| 遂溪县| 渑池县| 清镇市| 中方县| 浦县| 石家庄市| 河间市| 正安县| 莆田市| 德钦县| 漯河市| 东台市| 房山区| 梁山县| 聂荣县| 五峰| 肇源县| 湖北省| 汕尾市|