級別: 初級
Tilak Mitra (tmitra@us.ibm.com), IT 架構師, IBM
2004 年 2 月 01 日
本文描述了如何使用 WebSphere Studio Application Developer 中用于 XML 綁定的 Java 體系結構(Java Architecture for XML Binding,JAXB)來(lái)開(kāi)發(fā)實(shí)際的企業(yè)應用程序。JAXB 提供了一種便利的方法,可以 用來(lái)把 XML Schema 綁定到 Java 代碼中的表示,從而使開(kāi)發(fā)人員不需要了解很多 XML 本身的知識就可以把 XML 數據和處理功能融入到基于 Java 技術(shù)的應用程序中去。
在信息技術(shù)的世界里,越來(lái)越多的公司期望通過(guò)在因特網(wǎng)上提供業(yè)務(wù)服務(wù)以把IT應用到他們的業(yè)務(wù)中。為了從因特網(wǎng)業(yè)務(wù)中獲取最大限度的投資回報,企業(yè)正迅速地采用面向 企業(yè)到企業(yè) ( business-to-busines,B2B)的事務(wù)范例,該范例從參與企業(yè)中調用服務(wù)以最大化典型業(yè)務(wù)流程的自動(dòng)化程度。供應鏈管理業(yè)務(wù)流程就是這樣的一個(gè)例子,其中,制造企業(yè)的庫存與該企業(yè)的供應商的庫存緊密相連。
在最近幾年里,XML 成為 B2B 場(chǎng)景中的信息交換的最佳形式。已經(jīng)為橫向和豎向的市場(chǎng)部門(mén)創(chuàng )建了不同的 XML標準,而且正在努力在不同行業(yè)部門(mén)中使 XML達成一致的標準格式。
隨著(zhù)基于 XML 的信息交換的增加,企業(yè)必然要為使用 XML文檔而編寫(xiě)大量的 Java 代碼。JAXB 為把 XML Schema 綁定到 Java 代碼中的表示提供了便利的方法。這種方法使您不需要了解大量關(guān)于XML 本身的知識就可以容易地把 XML 數據和處理功能融入到基于 Java 技術(shù)的應用程序中去。
本文的目的是向開(kāi)發(fā)人員展示如何使用 WebSphere Studio ApplicationDeveloper 中的強大、簡(jiǎn)單、靈活的 JAXB 來(lái)開(kāi)發(fā)實(shí)際的企業(yè)應用程序,而與此同時(shí)您并不需要了解復雜的XML 解析技術(shù)。
盡管您不再需要擔心 XML 解析技術(shù),但您還是需要進(jìn)行一些研讀!JAXB 構建于 XML Schema之上。為了利用 JAXB 的強大功能您需要充分了解 XML Schema。通過(guò) XMLschema 可以很好地表示業(yè)務(wù)范圍對象和它們的結構關(guān)系,這使您能夠更好地理解XML Schema 的強大功能。JAXB 的本質(zhì)是 XML Schema 為 Java 對象和自身細微差別所作的靈活自定義。JAXB 的自定義同樣遵循 XMLSchema 的規則。在完成了創(chuàng )建 Schema 的艱苦工作后,把 JAXB 自定義添加到業(yè)務(wù)范圍對象模型中(用 XML Schema表示)就很簡(jiǎn)單了。
本文假設您理解:
您必須安裝如下產(chǎn)品以完成本文中的步驟:
雖然大多數的用戶(hù)都熟悉 Application Developer,但我們還是需要對 Java WSDP 進(jìn)行一些介紹。來(lái)自 Sun Microsystems 的 Java Web Services Developer Pack(JavaWSDP)是一個(gè)免費的集成工具包,可以用來(lái)構建、測試和部署采用最新的 Web服務(wù)技術(shù)和標準實(shí)現的 XML 應用程序、Web 服務(wù)及 Web 應用程序。您將會(huì )需要該包中的 JAXB編譯器和運行時(shí)庫來(lái)執行本文中的步驟。請參閱 參考資料部分來(lái)下載JWSDP。
面向對象編程(object-oriented programming,OO)中有兩個(gè)關(guān)鍵概念:類(lèi)和對象。 類(lèi)提供軟件概念和實(shí)體的結構,而 對象是類(lèi)的真實(shí)的實(shí)例。在 XML 表示中可以作相似的類(lèi)比。您可以把 XML Schema 看作是可用于創(chuàng )建 XML 文檔的組織和結構。Schema(在 XML 中)和類(lèi)(在 OO 中)是概念性構件,而文檔(在 XML 中)和對象(在 OO中)是符合各自概念性構件的真實(shí)的實(shí)例。
使用 Java 對象和類(lèi)與使用 XML 有根本的不同。JAXB 引入了數據綁定的概念以在 XML Schema 和 Java 類(lèi)之間建立通信。于是 JAXB 就可以利用映射來(lái)把 XML 文檔轉換成 Java 類(lèi),反之亦然。JAXB Schema 編譯器基于 XML Schema 的結構來(lái)創(chuàng )建 Java 類(lèi)和接口。于是就可以在編組和解組的過(guò)程中使用 JAXB 庫。 編組(Marshalling)是從一個(gè)或多個(gè) Java 對象創(chuàng )建 XML 文檔的過(guò)程,而 解組(unmarshalling)是從 XML 文檔創(chuàng )建一個(gè) Java 對象的過(guò)程。
為了在 J2EE 或任何基于 Java 的應用程序中使用 JAXB,第一步就是運行 JAXB 編譯器: xjc,由它創(chuàng )建 Java 類(lèi)和接口。為 XML Schema 中的每個(gè)元素定義生成一個(gè)或兩個(gè) Java 接口和相應的實(shí)現類(lèi)。生成實(shí)現類(lèi)所在的包與生成接口所在的包是相分離的。除了接口和實(shí)現類(lèi),還生成特定于 JAXB 的類(lèi)。使用這些類(lèi)來(lái)執行編組和解組,以在其他事物中創(chuàng )建實(shí)現類(lèi)的實(shí)例。請注意僅通過(guò)由 JAXB 編譯器生成的一個(gè)工廠(chǎng)類(lèi)來(lái)實(shí)例化實(shí)現類(lèi)。用來(lái)與 JAXB 創(chuàng )建的 Java 對象一起使用的兩個(gè)最重要的類(lèi)是:
![]() ![]() |
首先,我們需要按照如下步驟設置我們的開(kāi)發(fā)環(huán)境:







現在,我們已在 Application Developer 中設置好了我們的開(kāi)發(fā)環(huán)境。
![]() ![]() |
我們將要開(kāi)發(fā)的示例是一個(gè)簡(jiǎn)單的圖形用戶(hù)界面(graphical user interface,GUI)菜單系統。Widget是概念性元素,它定義了構成圖形用戶(hù)界面的整套繪圖組件。Widget的例子有矩形(rectangle)、正方形(square)、圓形(circle)以及其他一些可拖拉的可視組件。我們的簡(jiǎn)單 GUI由三個(gè)可視組件組成,它們分別是矩形、正方形和圓形。Widget組件封裝了一組以任意順序排列的可視組件(矩形、正方形和圓形)??蛻?hù)端可以通過(guò)給定的 XML文檔來(lái)構造可視組件,然后檢索每個(gè)可視組件的詳細信息,以用于任意方式的客戶(hù)端請求。
這部分的余下內容將舉例說(shuō)明并解釋示例場(chǎng)景的 XML Schema。
清單 1.示例場(chǎng)景的 XML Schema <?xml version="1.0" encoding="UTF-8> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" jxb:version="1.0" xmlns:domainObjects="http://www.ibm.com/domainobjects" targetNamespace="http://www.ibm.com/domainobjects" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jxb:extensionBindingPrefixes="xjc"> <xsd:annotation> <xsd:appinfo> <jxb:globalBindings collectionType="java.util.ArrayList" fixedAttributeAsConstantProperty="true" generateIsSetMethod="false" enableFailFastCheck="false" choiceContentProperty="false" underscoreBinding="asWordSeparator" typesafeEnumBase="xsd:NCName" typesafeEnumMemberName="generateError" enableJavaNamingConventions="true" bindingStyle="elementBinding"> <xjc:serializable /> <xjc:superClass name="com.ibm.domainobjects.Shape" /> </jxb:globalBindings> <jxb:schemaBindings> <jxb:package name="com.ibm.domainobjects" /> </jxb:schemaBindings> </xsd:appinfo> </xsd:annotation> <xsd:element name="UIWidgets" type="domainObjects:Widgets" /> <xsd:complexType name="Rectangle"> <xsd:attribute name="width" type="xsd:integer"/> <xsd:attribute name="height" type="xsd:integer"/> </xsd:complexType> <xsd:complexType name="Square"> <xsd:attribute name="length" type="xsd:integer"/> </xsd:complexType> <xsd:complexType name="Circle"> <xsd:attribute name="radius" type="xsd:integer"/> </xsd:complexType> <xsd:complexType name="Widgets"> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:annotation> <xsd:appinfo> <jxb:property name="Widgets" /> </xsd:appinfo> </xsd:annotation> <xsd:element name="rectangle" type="domainObjects:Rectangle" /> <xsd:element name="square" type="domainObjects:Square" /> <xsd:element name="circle" type="domainObjects:Circle" /> </xsd:choice> </xsd:complexType> </xsd:schema> |
Schema 注釋
xsd:annotation元素是 xsd:appinfo和 xs:documentation元素的容器,它包含了附加信息。這兩個(gè)元素專(zhuān)用于保存機器可處理(machine-processable)的( xsd:appinfo)信息和人工可閱讀的文檔(human readable documentation)( xsd:documentation)。
用藍色高亮顯示的部分表示特定于 JAXB 的全局 Schema 自定義,可用于整個(gè) Schema 文件。用紅色高亮顯示的部分表示特定于 JAXB的自定義,它定義了用于存放生成的文件的包;在本例中就是 com.ibm.domainobjects。
藍色 globalBindings 部分的 collectionType = java.util.ArrayList表示在 Java對象內部創(chuàng )建的任何集合都符合 Java 中的 List接口。
xjc:serializable元素確保生成的所有類(lèi)都是可序列化的。當通過(guò)有線(xiàn)來(lái)發(fā)送和接收對象,而數據在不同的應用程序間傳輸要進(jìn)行分層時(shí),這一點(diǎn)特別重要。
還定義了一個(gè)名為 Shape的 超類(lèi)(superClass)。這表示在這個(gè) Schema中定義的所有元素都有一個(gè)共同的名為 Shape的超類(lèi)。在這里展示它是為了說(shuō)明從 Schema 創(chuàng )建的類(lèi)也可以訪(fǎng)問(wèn)外部類(lèi),這些外部類(lèi)不是由 JAXB 編譯器創(chuàng )建的。
Widgets元素的定義表示定義了名為 Widgets 的屬性。如果沒(méi)有定義這個(gè)屬性,那么綁定編譯器將會(huì )自動(dòng)為選擇的列表(用于矩形、正方形和圓形)生成一個(gè)名稱(chēng)。該自動(dòng)生成通常采用子元素的名稱(chēng),并用“or”把這些名稱(chēng)組合起來(lái)。于是,列表的訪(fǎng)問(wèn)器名稱(chēng)將會(huì )像是這樣的: java.util.List getRectangleOrSquareOrCircle();
很明顯,上面的名稱(chēng)不是很有意義。 jxb:property name="Widgets" 表示存取器方法將是 getWidgets,這當然比自動(dòng)生成的名稱(chēng)更為直觀(guān)。
在示例中,JAXBTester 類(lèi)說(shuō)明了:
在 XML Schema 中還可以使用其他不同的自定義方式。要了解有關(guān) JAXB 自定義的詳細說(shuō)明,請參閱 參考資料。
![]() ![]() |
您只需運行一次 JAXB 編譯器。如果 Schema 沒(méi)有改變就不需要再次運行編譯器。然而,如果 Schema 經(jīng)過(guò)了一些改變,您將需要再次執行 JAXB編譯器的預處理步驟,以重新生成 Java接口和類(lèi)。這種情況下,在再次運行預處理步驟之前刪除先前運行 JAXB 編譯器時(shí)所生成的全部類(lèi)是可取的做法。在 Schema中的元素被刪除的情況下,這樣做是有幫助的。再次運行編譯器生成的類(lèi)不會(huì )刪除先前生成的類(lèi),于是來(lái)自前面版本 Schema 的未被使用的類(lèi)將會(huì )保留下來(lái)。
既然類(lèi)已生成,有趣的部分就開(kāi)始了!現在是使用生成的類(lèi)把 XML 文檔轉換成 Java類(lèi)的時(shí)候了,反之亦然。我們將專(zhuān)注于名為 JAXBTester的客戶(hù)端類(lèi)。
該類(lèi)示范了三個(gè)動(dòng)作。它首先創(chuàng )建 JAXB上下文并獲取所需的句柄。然后它示范如何使用句柄從 XML 文檔創(chuàng )建 Java 對象樹(shù)。它還展示如何實(shí)例化不同的 Java 對象和它們的屬性集,最后展示這些 Java對象如何利用所需的句柄來(lái)生成 Java 對象樹(shù)的 XML 表示。
分析 JAXBTester
JAXBTester 有三個(gè)方法,如下所述:
請注意您甚至不需要編寫(xiě)一行 XML代碼!轉換的細節都包含在生成的類(lèi)里了。
![]() ![]() |
運行客戶(hù)端類(lèi)之前,我們必須進(jìn)行如下步驟:
您現在已做好一切準備來(lái)運行該樣本,請您自行檢查結果。
![]() ![]() |
本文向我們介紹了JAXB 的基礎內容。它向您展示了在不需要了解 XML解析的情況下,您可以如何使用 Application Developer 中的 JAXB來(lái)創(chuàng )建 J2EE 應用程序。
學(xué)習 JAXB 最好的方法是首先要非常熟悉 XML Schema并達到運用自如的程度,然后再學(xué)習JAXB 自定義的技巧。而學(xué)習 XML Schema的最好方法是拿起一本書(shū)來(lái)閱讀,然后把書(shū)中的概念應用到現實(shí)世界的場(chǎng)景中去,以利用 XML schema的不同特征。O'Reilly 出版的 XML Schema是我最喜歡的書(shū)。
![]() ![]() |
![]()
|
| 名字 | 大小 | 下載方法 |
|---|---|---|
| JAXBTestEAR.zip | 3.5 KB | HTTP |
![]() | ||||
![]() | 關(guān)于下載方法的信息 | ![]() | ||
![]() | ||
![]() | ![]() | Tilak Mitra 是一位認證的 IT 架構師,他在位于 Fort Lauderdale/Miami 地區的 AIS 的 EAD Southeast 部門(mén)工作。他專(zhuān)門(mén)研究基于 J2EE、MQ 以及其他 EAI 技術(shù)的大中型企業(yè)應用程序體系結構。 |
聯(lián)系客服