top
Loading...
XML和J2EE的完美結合
當前,Java 2平臺企業版(J2EE)架構在廠商市場和開發者社區中倍受推崇。作為一種工具,可擴展標記語言(XML)簡化了數據交換、進程間消息交換這一類的事情,因而對開發者逐漸變得有吸引力,并開始流行起來。自然,在J2EE架構中訪問或集成XML解決方案的想法也很誘人。因為這將是強大系統架構同高度靈活的數據管理方案的結合。

XML的應用似乎是無窮無盡的,但它們大致上可以分為三大類:

●簡單數據的表示和交換(針對XML的簡單API(SAX)和文檔對象模型(DOM)語法解析,不同的文檔類型定義(DTDs)和概要(schemas))
●面向消息的計算(XML-RPC(遠程過程調用),SOAP協議,電子化業務XML(ebXML))
●用戶界面相關、表示相關的上下文(可擴展樣式表語言(XSL),可擴展樣式表語言轉換(XSLT))

這幾類應用在J2EE架構中恰好有天然的對應:數據表示和交換功能是EJB組件模型中持久化服務(persistence services)的一部分,基于消息的通訊由Java消息服務(JMS)API來處理,而界面表示正是Java服務器頁面(JSP)和Java Servlets的拿手好戲。

在本文中,我們將看到當今基于J2EE的應用里,XML是如何在上述幾個方面進行應用的,以及在相關標準的未來版本中這些應用將會如何發展。

基礎:數據的表示和交換

原型化的XML應用(假設有的話)的內容通常是:數據以XML格式存放,為了進行顯示、修改甚至寫入某個XML文檔而經常被讀入到某個對象模型中。作為例子,假定我們正處理多種類型的媒體(圖品、視頻、文本文檔等等),并且用下面這個簡單的XML DTD來描述這些媒體的元數據:

<!-- DTD for a hypothetical media management system -->
<!-- Media assets are the root of the object hierarchy. Assets are also
hierarchical - they can contain other assets. -->
<!ELEMENT media-asset (name, desc?, type*, media-asset*, urn)>
<!-- Metadata about the asset -->
<!ELEMENT name (#PCDATA)>
<!ELEMENT desc (#PCDATA)>
<!ELEMENT type (desc, mime-type?)>
<!ELEMENT mime-type (#PCDATA)>
<!ELEMENT urn (#PCDATA)>

以下是一個基于上述媒體DTD的XML文檔,描述了與某個課程講座相關的內容:

<?xml version="1.0" ?><!DOCTYPE media-asset PUBLIC "-//Jim Farley//DTD
Media Assets//EN" "http://localhost/Articles/Sun/dtds/media.dtd">
<media-asset>
<name>第14講</name>
<desc>與第14講相關的所有內容</desc>
<!-- 內容對象"lecture 14"的一套子組件 -->
<media-asset>
<name>講座的幻燈片</name>
<type>
<desc>MS PowerPoint</desc>
<mime-type>application/vnd.ms-powerpoint</mime-type>
</type>
<urn>http://javatraining.org/jaf/E123/lecture-
14/slides.ppt</urn>
</media-asset>
<media-asset>
<name>講座的視頻片斷</name>
<type>
<desc>RealPlayer streaming video</desc>
<mime-type>video/vnd.rn-realvideo</mime-type>
</type>
<urn>http://javatraining.org/jaf/E123/lecture-
14/lecture.rv</urn>
</media-asset>
<!-- 講座開始 -->
<urn>http://javatraining.org/jaf/E123/lecture-14/index.jsp</urn>
</media-asset>

從Web或者企業級應用的角度看,能以這種方式訪問數據真是一種福音,因為它體現了高度的可移動性,使我們與元數據的實際資源本身隔離。這些資源可能來自一個關系數據庫系統、某種活動媒體服務器或者Web服務器上的一個靜態XML文檔,等等。如果想把這些數據加載到Java應用中,我們可以從當前眾多的Java語言XML解析器中選用一個,通過它將XML數據裝入一個DOM文檔,最后遍歷文檔,將所有這些數據轉換到我們應用系統的對象模型中。

下面是個簡單的基于DOM的解析程序,可對上述的媒體DTD進行解析。解析器用的是Apache Xerces:

package jaf.xml;
import java.util.*;
import java.io.IOException;
import org.w3c.dom.*;
import org.xml.sax.*;

// XML文檔解析程序,使用上述媒體DTD.
public class MediaParser implements ErrorHandler {
/** 使用Apache Xerces解析器 */
org.apache.xerces.parsers.DOMParser mParser =
new org.apache.xerces.parsers.DOMParser();
/** 構造函數 */
public MediaParser() {
// 告訴解析器驗證并解析文檔
try {
mParser.setFeature( "http://xml.org/sax/features/validation",
true);
}
catch (SAXException e) {
System.out.println("Error setting validation on parser:");
e.printStackTrace();
}
// 設置解析器的錯誤處理句柄
mParser.setErrorHandler(this);
}
/** 解析指定的URL,返回找到的XML文檔
*/
public Document parse(String url) throws SAXException, IOException {
mParser.parse(url);
Document mediaDoc = mParser.getDocument();
return mediaDoc;
}
/** 解析指定URL的XML文檔,將內容轉換成 MediaAsset 對象
*/
public Collection loadAssets(String url) throws SAXException,
IOException {
Document doc = parse(url);
Collection assets = new LinkedList();
NodeList assetNodes = doc.getElementsByTagName("media-asset");
for (int i = 0; i < assetNodes.getLength(); i++) {
Node assetNode = assetNodes.item(i);
MediaAsset asset = new MediaAsset(assetNode);
assets.add(asset);
}
return assets;
}
/**
* 錯誤處理代碼(為簡潔起見省略了)
*/
}

MediaParser類的構造函數初始化了一個Xerces DOM解析器。parse()方法告訴解析器到哪個URL去找XML源,然后得到結果文檔并返回。loadAssets()方法調用parse()方法從某個XML源加載文檔,然后為文檔中找到的每個“media-asset”節點創建一個MediaAsset對象。

以下是一個使用MediaAsset類的例子:

package jaf.xml;
import java.util.*;
public class MediaAsset {
// 資源元數據
private String mName = "";
private String mDesc = "";
private Collection mChildren = new LinkedList();
private Vector mTypes = new Vector();
private String mUrn = "";
protected MediaAsset(org.w3c.dom.Node assetNode) {
// 為簡潔起見省略后面代碼
.
.
.
}
}

因為篇幅的關系省略了MediaAsset類的詳細代碼,但應用模式依然是清晰的。MediaAsset類遍歷文檔的節點,當它碰到不同的子節點時,它用子節點的內容填充自己的成員數據。如果它發現了一個嵌套的子資源節點,它只需要創建一個新的MediaAsset對象,然后將子資源節點的數據填充到新對象的成員數據中。

實現上述處理的方法數不勝數。我們還可以使用其他的解析器或解析器架構,如Java API for XML Parsing (JAXP)。除了使用DOM模型外,事件驅動的SAX模型也可用于解析XML。類似的程序也可用來產生XML數據——前提是允許產生新的數據對象(在本例中是MediaAsset),它可將其相應的XML實體插入到DOM中,然后將DOM輸出到一個流中(諸如一個文件,一個Socket,或者一個HTTP連接...)。還有其他更高層次的標準,可將XML映射到Java對象的過程進一步自動化(或簡化)。例如,使用XML概要(Schema)和XML綁定處理引擎,您可以半自動地將滿足某個XML 概要的XML數據轉變成Java數據對象。代表性的引擎是Castor,是由ExoLab小組管理的一個開放源代碼項目的產物。上述使用Xerces DOM的簡單例子僅僅是演示了這一處理過程的底層模型。

上述示例表明,在Java環境中解析或產生XML是非常方便的,這與J2EE沒有必然關聯。格式化為XML的數據可以從應用程序的任何層次流入或輸出,這使得與外部系統的集成性無可限量。但我們能否以一種更為直接的方式將XML數據源集成到J2EE架構中去呢?
作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗