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

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

2009-02-05
作者:许 晖

引言

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

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

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

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

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

1.1 XML模型?

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

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

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

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

(2)?? 嵌套定義?

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

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

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

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

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

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

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

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

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

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

1.3?存在的問(wèn)題?

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

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

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

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

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

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

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

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

(2)?Castor[5]?

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

(3) JiBX[6]?

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

(4)?Zeus[7]?

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

(5)?Quick[8]?

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

2.3?存在的問(wèn)題?

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

3.結(jié)論

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

參考文獻(xiàn)

[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)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。

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