DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 通過 Java 編程處理 XML 服務定義
通過 Java 編程處理 XML 服務定義
編輯:XML詳解     

SOA 提供了一系列服務,其中一些服務由用戶使用,而另一些則由計算機使用。事實上,由計算機使用的這些服務通常使 SOA 具有幾分遞歸結構。本文將介紹一種簡單的方法,可定義由 Internet 服務提供商(ISP)使用的服務。之所以選擇這種類型的提供商是因為大部分人對它比較熟悉。然而,其中的原理並不限於通信提供商:可以應用於所有類型的服務提供商 — 銀行、股票代理、公用事業公司等等。

本文假設某個 ISP 對其全部或部分基礎設施實現了 SOA。該提供商輸出的服務之一就是提供一種基於 Web 的工具,用戶可以借助該工具修改他們的服務配置文件。

本文的目的

撰寫本文之際,SOA 技術仍然處於發展階段,並且很多大型軟件供應商還在開發各自的 SOA 產品。因此,SOA 領域目前綜合了各種技術,包括 Java Business Integration (JBI)、Intelligent Event Processing 和 Business Process Execution Language (BPEL) 服務器。因此,在將各種技術融入到一個解決方案之前,想要從 SOA 中受益的用戶組織很可能需要進行大量投資。通過對 SOA 布置如此高的復雜性,行業提前為實現供應商定位鋪好了道路,即使 SOA 其中的一項承諾是實現基於標准、面向組件、獨立於供應商的計算。在開始代價高昂的遷移過程前,用戶組織能夠獲得一些實用的 SOA 使用體驗嗎?

為回答這個問題,本文通過簡單的 XML 和一些 Java 代碼演示了幾個重要的 SOA 原理。本文並不打算介紹 SOA 領域中的所有內容;相反,我們只介紹其中的一些關鍵部分。例如,您可以考慮使用 RSS 發布 XML 服務定義。但是,在本文的例子中,傳輸機制使用的是 Java 工具。

這種聚焦式方法的優點就是用戶組織中的 Java 開發人員可以使用其中的理念構建自己的簡單的試驗性 SOA。這種試驗模式有助於組織實現 SOA 的商業效益。後者包含對業務服務建模,例如計算服務、用戶自助服務、更好的自動化服務和更具響應性的服務。您可以將上述的遷移作為一個獨立試驗實現,與現有業務流程並行運作。

用戶組織不需要進行大型投資就可實現一個試驗性質的 SOA。通過這種方式,陳述特定於組織的 SOA 需求時可以脫離任何供應商實現。實際上,某些較小的用戶組織可以繼續使用他們的試驗性 SOA 模式,只在後期遷移到軟件供應商提供的大型商用解決方案。


自助服務趨勢

對於大多數服務提供商來說,自助服務正在發展為一種趨勢 — 特別是那些資金緊張的 ISP。因此,如果您需要更多帶寬(進行下載或玩在線游戲),您可以登錄到提供商的 Web 站點並通過 Web 頁面自動升級與提供商的連接。讓我們看一個具體的例子:清單 1 展示了一個簡單的基於 XML 的用戶服務配置文件。


清單 1. 一個簡單的基於 XML 的服務描述
                
<ServiceInstance>
<Customer>Josephine Bloggs</Customer>
<Package>Internet</Package>
<Bandwidth>1mbps</Bandwidth>
<DownloadLimit>1Gbyte</DownloadLimit>
<Uptime>95</Uptime>
</ServiceInstance>

代碼解釋了這個用戶 XML 服務模型。該模型包括:

  • 一個服務實例
  • 客戶名字
  • 服務包的名稱
  • 已配置的帶寬量
  • 每月允許的下載限度
  • 提供商正常運行時間保證

無疑,服務定義可以比此處的例子復雜很多。其他內容可能包括客戶地址、賬單明細、往返延遲、加密和服務信用信息等。重點是,越來越多的提供商提供如 清單 1 所示的 Web 訪問細節。某種程度上講,這種嘗試可以減少支持電話的花銷和發生頻度。有趣的是,這種基於 Web 的服務可以使用戶覺得為他們提供服務的是較為先進的提供商。這實現了雙贏的局面,因為客戶可以更好地訪問他們的服務數據,而提供商可以銷售無需他們插手的服務包。授權的用戶可以修改如 清單 1 所示的一些服務參數 — 例如,配置的帶寬。隨之修改的是用戶每月的訂購費用。

因此,清單 1 中的代碼形成了基於 XML 的服務模型的基礎。通過簡單地與在線表單進行交互,用戶可以修改可寫的服務元素(例如帶寬)。通過在線表單進行的修改將被記錄,然後反映到可由用戶配置文件修改的後端服務中。這是一種實現自助服務的標准方法。

然而,您將要了解的是另一種更加松散耦合的自助服務 — 使用這種服務,用戶可以通過在網絡中傳輸 清單 1 中的 XML 內容修改數據。在這種場景中,所傳輸的 XML 內容可通過一個 Java 客戶機進行修改,後者可運行在台式機、筆記本電腦、甚至某種資源受限的設備上(例如手機),然後將數據發回給網絡服務提供商。這種機制超越了基本的 Html 頁面模型並采納了 SOA 思想。


將服務定義 XML 文檔傳輸給使用 Java 技術的客戶機

Java 技術和 XML

Java 技術和 XML 幾乎成為了同義詞。實際上,我通過 IBM 工具對整篇文章應用了 XML 格式。盡管 XML 取得了顯而易見的巨大成功,仍需注意 XML 是一種相當笨拙的技術,例如 <start><end> 標簽會增加大量帶寬並在通過網絡傳輸數據時處理系統開銷。然而,忽略這種特性,XML 確實提供了一些強大的處理工具。這些工具(本文將探討其中的兩種)基本上解決了數據表示和解析問題(後者長久以來一直難以解決)。現在,通過使用 XML 工具,各種技術級別的程序員都可以實現專業的標准化解析。

Java 技術為 XML 數據處理提供了一些真正強大的工具(請參見側欄 Java 技術和 XML)。如果將 清單 1 中的內容看作是給定數據集的基於 XML 的呈現,那麼您還可以使用其他方式進行呈現。構成 清單 1 基本內容的原始數據一般保存在數據庫中。因此,您如何將這些數據打包成 XML?

清單 2 中的內容摘取自本文附帶的 Java 文件 encodeXML.Java.(相關文件可從 下載 部分獲得)。encodeXML.Java 類對 XMLEncoder 類的對象進行了實例化。如您所見,這個對象隨後在當前目錄中創建了名為 xmldata.XML 的文件。下一步是將 XML 數據值插入到文件中,這可以通過調用一連串的 writeObject() 方法實現(清單 2 對此進行了說明)。顯然,在生產環境中,清單 2 中硬編碼的文本字符串將來自數據庫這樣的持久性存儲。無論何種情況,可以看到 XML 數據文件的創建非常簡單。


清單 2. 使用 XML 格式編碼數據
                
XMLEncoder e = new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream("xmldata.XML")));
e.writeObject("Josephine Bloggs");
e.writeObject("Internet");
e.writeObject("1mbps");
e.writeObject("Gbyte");
e.writeObject("295");
e.close();

執行 清單 2 中的程序後,程序的執行目錄中將出現一個名為 xmldata.XML 的文件。清單 3 解釋了新創建文件包含的內容。


清單 3. 生成的 XML 數據
                
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_06" class="java.beans.XMLDecoder">
<string>Josephine Bloggs</string>
<string>Internet</string>
<string>1mbps</string> 
<string>Gbyte</string> 
<string>295</string>
</Java>

您可以通過網絡將 清單 3 中的文件傳輸給等待狀態中的客戶機 — 使用 Java 技術即可創建。清單 4 展示了一個簡單的例子。


清單 4. 跨越網絡傳輸文件
                
byte[] bytes = new byte[BUFFER_SIZE];
FileInputStream inputFile = null;
try
{
File file = new File("xmldata.XML");
if (file.exists())
{
inputFile = new FileInputStream(file);
int ch = inputFile.read(bytes, 0, BUFFER_SIZE);
while (ch != -1)
{
output.write(bytes, 0, ch);
ch = inputFile.read(bytes, 0, BUFFER_SIZE);
}
}

清單 4 中的代碼創建了一個長度緩沖區 BUFFER_SIZEBUFFER_SIZE 常量的值可以是 1024 或更高。通過調用 inputFile.read() 方法將輸入文件(xmldata.XML)的內容讀取到緩沖區中。進行緩沖之後,output.write() 方法將文件數據寫入到 OutputStream 對象的套接字中。最後一步將數據通過網絡發送到等待中的客戶機中。這些功能居然只需要這麼少的代碼!

接下來,您需要使客戶機處理傳入的 XML 數據。

接收數據的 Java 客戶機獲得 XML 內容(並不是 XML 文件)

客戶機如何接收 XML 數據?同樣,對於 Java 技術來說這只是小事一樁。數據接收通過一個套接字對象完成。清單 5 展示的代碼將接收傳入的數據並將數據推入到 ArrayList 類的對象中。

客戶機現在必須解決兩個與所接收數據項的數量有關的問題。由於這是一個松散耦合的場景,您必須假定客戶機並不清楚服務配置文件(即 清單 1 中的代碼)中包含了多少 XML 數據項。因此,您必須確定一些方法來接收和處理精確的數據項數量。第二個問題比較容易解決,就是如何保存處理過的數據。您將看到,清單 5 同時解決了這兩個問題。


清單 5. 提取嵌入的 XML 數據
                
XMLDecoder d = new XMLDecoder(input);
try
{
while (true)
ArrayList<Object[]> rowList = new ArrayList<Object[]>();
{
String dataItem = (String)d.readObject();
System.out.println("XML decoded data: " + dataItem);
rowList.add(dataItem);
}
}
}
catch (Exception exc)
{
if (exc instanceof ArrayIndexOutOfBoundsException)
{
// No more records to process
System.out.println("Parsed all XML records - " +
	"threw exception. Number of rows: " + rowList.size());
}
}

d.close();

通過一個有限循環 while (true),您可以確定期望的到來數據項的數量。該代碼將一直執行循環,直到接收到最後一個數據項,此時將拋出一個異常(ArrayIndexOutOfBoundsException)。您必須使用這種異常機制,除非客戶機已經了解期望的數據項數量。

InputStream 對象接收的 XML 數據被保存在 ArrayList 類的一個對象中。該類對於此類應用程序非常有用。完成類定義之後,ArrayList 具有一個特定的容量,總是匹配底層列表的大小。在添加元素時,ArrayList 對象的容量將自動擴展。因此,您無需擔心會超過數組的極限,因為該類將為您處理這一問題。

此時,客戶機具有 清單 1 中數據的副本。客戶機現在可以將帶寬元素修改為所需的值,然後反向執行文件傳輸過程,從客戶機發送到服務器。通過將 XML 文件從服務器移動到客戶機,客戶機實際上使用了這一服務。更新後的數據被發送回服務器以完成事務。當然,服務提供商必須驗證傳入的數據並提供所需的帶寬更改。

本文描述的這種模式首先將一個 XML 文件通過網絡傳輸到客戶機。客戶機將文件數據作為流進行接收,然後將其解析為一個內存駐留對象。客戶機隨後對內存駐留對象進行更改,然後反向執行傳輸過程,將對象發回到服務器。

還存在一種服務,其中 XML 數據被完整無缺地從服務器傳輸到客戶機。這種場景中,客戶機使用某種形式的文件傳輸協議(例如 FTP)獲得完整的文件副本。由於文件傳輸是一種標准技術,這裡不作過多介紹,您只需了解客戶機將下載 清單 1 中服務配置數據的一個文件副本。此時,客戶機需要解析並修改文件,然後傳輸回服務器,這種模式的工作原理是什麼?

一種基於 XML 文件的 Java 機制

客戶機現在將服務配置文件的副本保存在磁盤中。必須對該文件進行解析以提取 XML 數據。讓人意外的是,這實現起來有些難度,對於較大的文件尤其如此。解決問題的關鍵是使用合適的解析工具。本文中使用的工具是 dom4j,該工具允許您將 XML 數據解析為一個 Java 對象。您還可以使用一個基於 Simple API for XML (SAX) 的解析器,但是 SAX 是一種較低級的技術。您將看到,dom4j 工具僅需要很少的工作即可完成解析。清單 6 引用自本文附帶的 ProcessEventXML.Java 文件,展示了使用 dom4j 解析文件所需的主要元素。


清單 6. dom4j 處理 XML 數據
                
try
{
handler.treeWalk(handler.parse(new File(argv[0])));
}
catch (Throwable t)
{
t.printStackTrace();
}
}

public Document parse(File url)
throws DocumentException
{
SAXReader reader = new SAXReader();
Document document = reader.read(url);
return document;
}

public void treeWalk(Document document)
throws Exception
{
treeWalk(document.getRootElement());
}

基本上只需要兩種方法:parse()treeWalk()。當我運行經過編譯的類時,我獲得了如 清單 7 所示的輸出。如果您希望親自運行代碼,請確保下載、安裝 dom4j 副本,並添加到 CLASSPATH 中(最後一步就是將相應的 JAR 文件添加到您的 CLASSPATH 變量中)。然後,編譯 ProcessEventXML.Java 文件並使用以下命令運行程序:

Java ProcessEventXml ServiceDefinition.XML


清單 7. 使用 dom4j 處理 XML 文件
                
Java ProcessEventXml ServiceDefinition.XML
Josephine Bloggs Internet 1mbps 1Gbyte 95

正如您看到的,僅需少量工作即可整潔地顯示 XML 數據。這些工作都是由 dom4j 處理的。事實上,大部分工作是通過 treeWalk() 方法完成的,這是一種只有到達文件末尾才進行調用的遞歸式方法。這裡向您展示了 dom4j 的一個功能:在內存中進行處理。需要注意的是,該技術不適合用於特別大型的 XML 文件,特別是如果您的 Java 設備非常小的話。然而,在本文的例子中,XML 數據集非常小,因此使用這個功能不會產生問題。

您的基於文件的客戶機現在已經成功訪問了 XML 數據。客戶機可以根據需要修改數據並編寫新的 XML 文件。然後將其傳輸回服務器進行處理。像上文一樣,客戶機在這一過程中使用了該服務。

結束語

Java 技術為 SOA 設計和實現提供了經過優化的解決方案。通過使用簡單的基於 XML 文件的服務配置,您可以輕松地在網絡中移動客戶機數據。客戶機可以查看並修改這些數據,然後使用這些數據更新服務。本文中的服務由 ISP 提供,但是任何提供商都可以使用這種方法。

分享這篇文章……

digg 提交到 Digg del.icio.us 發布到 del.icio.us Slashdot 提交到 Slashdot!

這種客戶機服務的一個關鍵因素是工作流。商用 SOA 產品趨向於使用 BPEL 提供這種功能。而試驗性 SOA 模式可能使用簡單的消息傳遞模式 — 例如,Java Message Service (JMS) 應用程序編程接口(API)。正如我在簡介中提到的一樣,這種方法的優點是組織可以在為遷移到商用 SOA 解決方案而做出重大投資之前獲得一些 SOA 使用體驗。

除了工作流支持外,本文沒有涉及到的另一個重要問題是安全性。如果客戶機用戶修改了他們的服務配置,那麼需要對底層數據進行保護。同樣,Java 技術提供了一些方法可以實現安全性。

您還可以使用一種更粗糙的方法將 XML 服務配置數據表示為文件。客戶機隨後使用某種模式將這些文件傳遞到本地存儲中,然後您可以使用 dom4j 解析並修改文件數據。Java 技術也提供了一些工具簡化了這些操作。通過使用這些方法,任何規模的 Java 客戶機可以完全參與到 SOA 實現中。


XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved