《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 其他 > 业界动态 > 应用XML实现Java对象序列化技术简述

应用XML实现Java对象序列化技术简述

2009-02-05
作者:许 晖

引言

Java對象的序列化(serialization)是對象的持久存儲和對象狀態(tài)的網(wǎng)絡(luò)傳輸的關(guān)鍵環(huán)節(jié),在RMI(Remote Method Invocation)、JMS(Java Message Service)和EJB(Enterprise JavaBeans)中都有應(yīng)用。對象序列化可以實現(xiàn)分布式對象,例如RMI要利用對象序列化運行遠程主機上的服務(wù),就像在本地機器上調(diào)用對象一樣。對象序列化還可以實現(xiàn)對象狀態(tài)和數(shù)據(jù)的持久存儲,在對象序列化的過程中,不僅保留一個對象的數(shù)據(jù),而且遞歸保存對象引用的每個對象的數(shù)據(jù),從而記錄整個對象層次結(jié)構(gòu)和數(shù)據(jù),以便保存在文件中或在網(wǎng)絡(luò)連接上傳遞。利用對象序列化可以進行對象的“深復(fù)制”,即復(fù)制對象本身及引用的對象本身。JDK(JavaTM 2 SDK)提供了實現(xiàn)對象序列化功能的機制,開發(fā)人員可以利用ObjectOutputStream類的writeObject()方法把對象寫入字節(jié)流來實現(xiàn)對象的序列化(serialization),利用ObjectInputStream類的readObject()方法可以從字節(jié)流中讀取對象實現(xiàn)對象的反序列化(deserialization)。?

但是,在JDK所提供的序列化機制中,類必須實現(xiàn)java.io.Serializable接口或者java.io.Externalizable接口,其對象才可以被序列化,對于已有的系統(tǒng),如果要實現(xiàn)系統(tǒng)中對象的網(wǎng)絡(luò)傳輸,就會受到類型的限制從而導(dǎo)致直接序列化傳輸無法實現(xiàn)。此外,JDK的對象序列化機制是以二進制格式將對象寫入字節(jié)流的,數(shù)據(jù)格式依賴于JVM(Java Virtual Machine)的實現(xiàn),缺乏可讀性和通用性,限制了對象數(shù)據(jù)的存儲和管理。?

隨著Internet的發(fā)展,XML(Extensible Markup Language)已成為進行對象形式化描述和分布式數(shù)據(jù)交換的標(biāo)準。XML具有層次結(jié)構(gòu),很適合存儲對象的狀態(tài)數(shù)據(jù),而且XML格式的數(shù)據(jù)具有很強的可讀性和通用型,所以XML很適合用來實現(xiàn)對象的序列化,可以彌補JDK所提供的序列化機制的不足。越來越多的應(yīng)用場合需要直接從XML文檔中創(chuàng)建對象或者把對象狀態(tài)保存成XML文檔。?

本文介紹了應(yīng)用XML實現(xiàn)Java對象序列化的研究,分析了用XML建模實現(xiàn)對象序列化和用XML數(shù)據(jù)綁定技術(shù)實現(xiàn)對象序列化的方法以及用XML實現(xiàn)Java對象序列化的優(yōu)勢和局限。本文的后續(xù)篇幅共分為三部分,第一部分介紹構(gòu)建XML模型實現(xiàn)Java對象序列化的方法,第二部分介紹用XML數(shù)據(jù)綁定實現(xiàn)對象序列化的方法,最后一部分是總結(jié)。?

1.構(gòu)建XML模型實現(xiàn)Java對象序列化

1.1 XML模型?

隨著Internet的發(fā)展,XML已成為進行對象形式化描述和分布式數(shù)據(jù)交換的標(biāo)準。XML具有層次結(jié)構(gòu),很適合存儲對象的狀態(tài)數(shù)據(jù)和實現(xiàn)對象的序列化。在對象序列化的過程中,不僅需要保留一個對象的數(shù)據(jù),而且需要遞歸保存對象引用的每個對象的數(shù)據(jù),記錄整個對象層次結(jié)構(gòu)和數(shù)據(jù)。一般來說,一個對象會對應(yīng)一棵層次結(jié)構(gòu)的對象樹,對象的序列化需要完整地保留對象樹的結(jié)構(gòu)和數(shù)據(jù)信息。用XML實現(xiàn)對象的序列化,關(guān)鍵在于構(gòu)建合適的XML數(shù)據(jù)模型,完備地描述對象樹的信息,同時還要便于對象的反序列化。?

XML的層次結(jié)構(gòu)很適合構(gòu)建描述Java對象的數(shù)據(jù)模型,但是,簡單的利用XML的層次結(jié)構(gòu)還不足以完整地描述Java對象的結(jié)構(gòu)層次和數(shù)據(jù)信息,還需要針對Java對象的層次結(jié)構(gòu)作詳細的定義。在用XML構(gòu)建數(shù)據(jù)模型時,需要考慮以下幾個方面的問題:?

(1)?? 繼承關(guān)系?

類的繼承關(guān)系構(gòu)成了面向?qū)ο蟮幕緦哟谓Y(jié)構(gòu)。支持Java對象序列化的XML模型需要記錄類的完整的繼承關(guān)系,記錄和類結(jié)構(gòu)相關(guān)的數(shù)據(jù)信息,在反序列化時要能夠重新構(gòu)建對象的類的繼承關(guān)系,恢復(fù)數(shù)據(jù)。?

(2)?? 嵌套定義?

Java對象的數(shù)據(jù)成員可能是基本數(shù)據(jù)類型、Java對象和數(shù)組類型,所以Java對象一般都會引用到其他Java對象,在對象序列化時需要遞歸保存每一個所引用到的對象的數(shù)據(jù),這就要求XML數(shù)據(jù)模型能夠支持嵌套定義,記錄對象引用的層次結(jié)構(gòu)和對象數(shù)據(jù)。?

(3)?? 數(shù)組的描述?

Java對象的數(shù)據(jù)成員可能是數(shù)組類型。數(shù)組在Java中也是一個對象,但是數(shù)組對象沒有顯式的構(gòu)造函數(shù)和類定義,所以不能像一般對象一樣定義和處理。在用XML建模時需要對數(shù)組類型獨立定義,描述數(shù)組的整體信息和數(shù)組成員的對象數(shù)據(jù)。?

(4)???? 特殊元素的定義?

在用XML建模時需要定義基本數(shù)據(jù)類型和空對象(即null)等元素。?

1.2?已有的實現(xiàn)?

(1)? JosML (Java Object Serialization Markup Language)[2]?

文獻[2]中提出了用于Java對象序列化的XML模型JosML,該模型定義了基本數(shù)據(jù)類型,對象的嵌套關(guān)系和描述數(shù)組元素的模型,可以基本上實現(xiàn)Java對象的序列化。但是,這個模型沒有定義對象的類繼承關(guān)系,無法記錄和類型相關(guān)的數(shù)據(jù)信息。?

(2)? JSX (Java Serialization to XML)[3]?

JSX是一個用XML序列化Java對象的工具。JSX的XML模型定義了類的繼承關(guān)系和對象引用的嵌套關(guān)系,包含了數(shù)組類型的定義模型和基本數(shù)據(jù)類型、空對象、字符串類型的對象等元素的定義,是一個比較完備和成熟的Java對象序列化的XML模型。JSX可以完整地記錄Java對象的層次結(jié)構(gòu)和對象數(shù)據(jù)以及繼承關(guān)系,從而能夠用XML格式成功地實現(xiàn)所有Java對象的序列化和反序列化。?

1.3?存在的問題?

對象的序列化過程中需要動態(tài)獲得對象的狀態(tài),Java平臺提供的反射機制可以實現(xiàn)這個要求。Java平臺內(nèi)建的序列化機制雖然也可以得到對象的運行時狀態(tài),但是序列化結(jié)果是二進制格式,而且只限于Serializable對象,所以基于XML模型的Java對象序列化的實現(xiàn)一般都通過反射(reflection)機制完成。JosML和JSX在實現(xiàn)時都用到了反射機制。但是,用反射機制訪問類的非公有成員以及調(diào)用非公有的構(gòu)造方法時,如果當(dāng)前運行環(huán)境有安全策略限制,運行時會拋出相應(yīng)的SecurityException,導(dǎo)致序列化無法正常進行。由于Java安全模型的限制,在安全要求比較高的運行環(huán)境中,利用反射機制實現(xiàn)的XML格式的Java對象序列化工具的應(yīng)用將會受到限制。?

2.應(yīng)用XML數(shù)據(jù)綁定實現(xiàn)Java對象序列化

2.1?XML數(shù)據(jù)綁定?

XML數(shù)據(jù)綁定是指將XML文件的描述文檔(DTD或者XML Schema)映射為一系列的應(yīng)用類。對Java的XML數(shù)據(jù)綁定而言,就是將XML文件的描述文檔映射為一系列的Java類。通過讀取文檔把應(yīng)用類實例化為一棵對象樹,便于運行時訪問。相比較XML文檔模型而言,XML數(shù)據(jù)綁定簡單直觀,適合于文檔數(shù)據(jù)的應(yīng)用。XML數(shù)據(jù)綁定包括三個方面的內(nèi)容:一是編組(Marshalling),在內(nèi)存中為對象生成 XML 表示,即用XML序列化Java 對象的過程;二是解組(Unmarshalling),是與編組相反的過程,在內(nèi)存中根據(jù) XML 表示構(gòu)建一個對象;三是驗證(validate),包括兩方面,解組時要求XML數(shù)據(jù)文件是良定義的,符合生成java源文件的Schema約束,編組時要求內(nèi)存中的java類也是可編組的。所以,XML數(shù)據(jù)綁定技術(shù)和工具也可以用來實現(xiàn)XML格式的對象序列化。?

2.2?實現(xiàn)框架?

XML數(shù)據(jù)綁定的研究已經(jīng)有了很多成果,許多組織都推出了實現(xiàn)XML數(shù)據(jù)綁定的框架,如JAXB、Castor等,Java Community Process(JCP)中的 JSR-031 也正致力于定義一個標(biāo)準,確定標(biāo)準的接口。下面是目前Java平臺上主要應(yīng)用的一些XML數(shù)據(jù)綁定的實現(xiàn)框架:?

(1)?JAXB(Java Architecture for XML Binding)[4]?

JAXB是SUN、IBM和BEA等多家聯(lián)合發(fā)布的Java平臺的數(shù)據(jù)綁定標(biāo)準,并提供了參考實現(xiàn)。JAXB支持從XML Schema生成Java類,將 Java 語言代碼綁定到 W3C XML Schema 文法所定義的文檔,在此基礎(chǔ)上,JAXB可以利用XML實例文檔生成Java對象樹,也可以將Java對象樹的內(nèi)容重新寫到XML實例文檔中,從而可以實現(xiàn)基于XML的Java對象的序列化和反序列化。?

(2)?Castor[5]?

Castor是一個開放源碼的XML數(shù)據(jù)綁定的工具,支持根據(jù)XML Schema的綁定,同時也支持缺省綁定,可以完成從XML文檔到已有JavaBean之間的直接序列化綁定,允許沒有XML Schema參與工作。Castor在編組時只支持XML Schema所定義的數(shù)據(jù)類型,如果自定義的類作為數(shù)據(jù)成員,則必須定義映射文件。Castor要求綁定的Java類具有JavaBean的格式,即需要定義公共的缺省構(gòu)造方法,定義公共的get和set方法用來訪問屬性的值。在解組時,如果數(shù)據(jù)成員沒有寫入訪問接口(set方法),結(jié)果對象就不會有該數(shù)據(jù)成員的數(shù)據(jù)。Castor在用于Java對象的序列化時也有其局限性。?

(3) JiBX[6]?

JiBX 數(shù)據(jù)綁定框架在結(jié)構(gòu)和實現(xiàn)技術(shù)上和其他數(shù)據(jù)綁定框架有所不同。首先,JiBX沒有使用SAX2解析器的API,而是采用了拉(pull)解析器的API。其次,JiBX針對反射機制的性能劣勢和功能局限,采用了字節(jié)碼增強(Byte code enhancement)技術(shù)。此外,JiBX沒有采用以XML為中心的方法根據(jù)XML Schema或者DTD的定義生成代碼,而是采用了以Java為中心的方法,定義映射規(guī)則,實現(xiàn)映射綁定。[9]由于這個原因,JiBX無法直接應(yīng)用到Java對象的序列化中。但是,采用字節(jié)碼增強技術(shù)是用XML實現(xiàn)Java對象序列化的一個比較好的解決方案。?

(4)?Zeus[7]?

Zeus是根據(jù)XML文檔的DTD定義生成代碼的一種XML數(shù)據(jù)綁定工具,和其他數(shù)據(jù)綁定工具相比,Zeus易于使用但功能有限。目前Zeus的版本只支持DTD,在數(shù)據(jù)類型方面,Zeus 只支持 String,而不支持其它類型的值,例如int或Date,還缺乏對引用的支持,不能直接進行數(shù)據(jù)分解或編組圖結(jié)構(gòu),只能對根據(jù)DTD生成的Java類的對象作編組和解組操作。這也限制了Zeus在Java對象序列化上的應(yīng)用。?

(5)?Quick[8]?

Quick是一中比較靈活的XML數(shù)據(jù)綁定工具。和Zeus一樣,Quick根據(jù)XML文檔的DTD定義生成綁定的代碼,但Quick比Zeus復(fù)雜,功能也比Zeus強大。Quick使用一系列相當(dāng)復(fù)雜的步驟來根據(jù) DTD 文檔描述生成代碼,在此過程中使用了作為中間步驟的三個獨立的綁定模式文檔:QDML 文檔提供文檔描述,大致相當(dāng)于 DTD,不過添加了一些類型和繼承;QJML 文檔定義了 XML 到 Java 語言對象的綁定;QIML 文件基本上是 QJML 的編譯形式,可以用它來生成實際的綁定代碼。所以,應(yīng)用Quick實現(xiàn)Java對象的序列化也要受到描述文檔的限制。[9]?

2.3?存在的問題?

Java平臺上的XML數(shù)據(jù)綁定框架致力于將XML數(shù)據(jù)和Java對象綁定,實現(xiàn)將XML實例文檔轉(zhuǎn)換成Java對象樹。數(shù)據(jù)綁定框架在實現(xiàn)時,要么根據(jù)Schema、DTD或其他映射文件生成自己的數(shù)據(jù)類,然后要求開發(fā)者在應(yīng)用程序中使用,要么使用反射機制,通過使用 Java 虛擬機所知的類信息提供對數(shù)據(jù)的間接運行時訪問。第一種實現(xiàn)方法由于受到Schema、DTD或映射文件的限制,不能應(yīng)用于任意Java對象的序列化;第二種實現(xiàn)方法則受到反射機制的限制。JiBX中所用到的字節(jié)碼增強(Byte code enhancement)技術(shù)是解決這一問題的一個比較有效的方法。字節(jié)碼增強技術(shù)也同樣可以應(yīng)用到構(gòu)建XML數(shù)據(jù)模型序列化Java對象的實現(xiàn)中,解決第二部分提到的應(yīng)用反射機制的限制。?

3.結(jié)論

應(yīng)用XML序列化Java對象可以解決對象持久存儲和網(wǎng)絡(luò)傳輸?shù)膶嶋H應(yīng)用中所遇到的問題。直接構(gòu)建XML數(shù)據(jù)模型和利用XML數(shù)據(jù)綁定技術(shù)都可以在一定程度上實現(xiàn)基于XML的Java對象序列化,但在實現(xiàn)中都會受到反射機制的限制。雖然用字節(jié)碼增強技術(shù)可以解決一定的問題,但從根本上來說,這一問題的出現(xiàn)是由于對象序列化的要求和Java平臺安全模型之間的矛盾造成的。運行時強制訪問對象的內(nèi)部信息有悖于Java的安全模型。在解決對象序列化的問題的同時,還需要在兩者之間作取舍或折中。?

參考文獻

[1]?Fabian Breg, Constantine D. Polychronopoulos. Java Virtual Machine Support for Object Serialization, Concurrency Computation Practice and Experience, Vol. 15, 2003.?

[2]?HE Chengwan, YU Qiuhui. JosML-An XML Model for Java Object Serialization, Computer Engineering, Vol. 28, No. 1, 2002.?

[3]?Java Serialization to XML, http://jsx.org .?

[4]?JAXB (Java Architecture for XML Data Binding), http://java.sun.com/xml/jaxb/index.html .?

[5]?Castor,http://www.castor.org/ .?

[6]?JiBX, http://www.jibx.org/ .?

[7]?Zeus, http://zeus.enhydra.org/ .?

[8]?Quick, http://sourceforge.net/projects/jxquick/ .?

[9]?Dennis M. Sosnoski. XML in Java: Data binding, ?

http://www-900.ibm.com/developerWorks/cn/xml/x-databdopt/part1/index_eng.shtml,?

http://www-900.ibm.com/developerWorks/cn/xml/x-databdopt/part2/index_eng.shtml,?

http://www-900.ibm.com/developerWorks/cn/xml/x-databd3/index_eng.shtml,?

http://www-900.ibm.com/developerWorks/cn/xml/x-databd4/index_eng.shtml.?

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。

相關(guān)內(nèi)容