digester

Digester本來僅僅是Jakarta Struts中的一個工具,用於處理struts-config.xml配置檔案。顯然,將XML檔案轉換成相應的Java對象是一項很通用的功能,這個工具理應具有更廣泛的用途,所以很快它就在Jakarta Commons項目(用於提供可重用的Java組件庫)中有了一席之地。

基本簡介

如今Digester隨著Struts的發展以及其的公用性而被提到commons中獨自立項,是apache的一個組件 apache commons-digester.jar,通過它可以很方便的從xml檔案生成java對象.你不用再象以前通過jdom或者Xerces去讀取一個document對象.(jdom和Xerces仍然有它們的用武之地及強大之處,在其它套用里你也少不了它們) 。

工作原理

Digester由"事件"驅動,通過調用預定義的規則操作對象棧,將XML檔案轉換為Java對象。工作原理如下:

Digester底層採用SAX解析XML檔案,所以很自然的,對象轉換由"事件"驅動,即在識別出特定XML元素時(實際被細分為begin、body、end、finish四個時點),將執行特定的動作,比如創建特定的Java對象,或調用特定對象的方法等。此處的XML元素根據匹配模式(matching pattern)識別,而相關操作由規則(rule)定義。在轉換過程中,Digester維持了一個對象棧,可以看作對象轉換的工作檯,用來存放轉換中生成的、或是為轉換臨時創建的Java對象。對輸入XML檔案作了一趟完整的掃描後,對象棧的棧頂元素即為目標對象。由於Digester禁止了SAX解析的細節,使用者僅需關注轉換操作本身,大大簡化了轉換操作。

核心規則

對使用者而言,Digester的核心在於匹配模式與規則(matching pattern + rule)。

匹配規則示例如下:

<a> -- Matches pattern "a"

<b> -- Matches pattern "a/b"

<c/> -- Matches pattern "a/b/c"

<c/> -- Matches pattern "a/b/c"

</b>

<b> -- Matches pattern "a/b"

<c/> -- Matches pattern "a/b/c"

<c/> -- Matches pattern "a/b/c"

<c/> -- Matches pattern "a/b/c"

</b>

</a>

Digester提供了一些編程中經常用到的規則(rule),以下五類九個rule較為常用:

A:對象創建

1.ObjectCreateRule 當begin()方法被調用時, 此rule創建相應Java對象, 並將其push到Digester的對象棧上。當end()方法被調用時, 棧頂對象將被pop, Digester內所有對該對象的引用都將失效。

2.FactoryCreateRule 創建Java對象的另一種選擇。當待創建的Java對象沒有無參構造函式,或需要在創建時需要進行額外的設定時,需要用此rule。

B:屬性設定

3.SetPropertiesRule 當begin()方法被調用時, Digester使用標準的Java反射API,將棧頂對象的屬性設定為XML元素的同名屬性值。

4.SetPropertyRule 當begin()方法被調用時, Digester調用棧頂對象某指定屬性的設定方法,設定其值。

C:父子關係管理

5.SetNextRule 當end()方法被調用時, Digester將棧頂元素設定進次棧頂元素中(調用相應的設定方法)。

6.SetTopRule 當end()方法被調用時, Digester將次棧頂元素設定進棧頂元素中(調用相應的設定方法)。

D:任意方法調用

7.CallMethodRule 當end()方法被調用時, Digester將調用棧頂元素指定名稱的方法。除了方法名外,此rule還需要配置參數數目,參數類型。參數值一般通過CallParamRule得到。

8.CallParamRule 此rule內嵌於CallParamRule中,按順序(相對於0)定義了CallParamRule中參數值的來源,可選的來源包括當前XML元素的屬性或內容。

E:其它

9.NodeCreateRule 將XML檔案樹的一部分轉換為DOM節點,並push到Digester的對象棧上。

使用條件

使用Digester需要如下幾個軟體包:

Digester ,

BeanUtils,

Collections,

Commens-Logging,

還有一個遵循SAX(Simple API for XML)2.0或JAXP(Java API for XML Parsing) 1.1規範的XML解析器,如Xerces。

如果需要使用log4j做為日誌輸出,則亦請下載之。

使用方法

使用者通過調用Digester類的相關方法,來創建匹配模式與規則的映射序列。

比如,調用addSetProperties(String pattern),向Digester中加入SetPropertiesRule。

基本步驟如下:

1.創建Digester對象實例。

2.設定該Digester對象的配置屬性(可選)。

3.將需要的初始對象push到該Digester對象的對象棧上(可選)。

4.需要註冊所有的XML元素匹配模式與處理規則之間的映射關係。

5.用digester.parse()解析的XML文檔對象,得到目標對象。

簡單示例

1.foo.xml 數據源檔案

2.Foo.java 目標Java對象

3.Bar.java 目標Java對象

4.Entry.java 調用Digester的入口類

【foo.xml】

<?xml version="1.0" encoding="GBK"?>

<foo name="The Parent">

<bar id="123" title="The First Child"/>

<bar id="456" title="The Second Child"/>

</foo>

【Foo.java】

package org.easev.digester;

import java.util.HashMap;

import java.util.Iterator;

public class Foo {

private String name;

public void setName(String name) {

this .name = name;

}

public String getName() {

return name;

}

private HashMap bars = new HashMap();

public void addBar(Bar bar) {

bars.put(String.valueOf(bar.getId()), bar);

}

public Bar findBar(int id) {

return (Bar) bars.get(String.valueOf(id));

}

public Iterator getBars() {

return bars.keySet().iterator();

}

}

【Bar.java】

package org.easev.digester;

public class Bar {

private int id;

public int getId() {

return id;

}

public void setId(int id) {

this .id = id;

}

private String title;

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

}

【Entry.java】

package org.easev.digester;

import java.io.File;

import java.util.Iterator;

import org.apache.commons.digester.Digester;

public class Entry {

public static void main(String[] args) throws Exception {

//相對路徑定義與包名相關

File input = new File("org/easev/digester/foo.xml");

Digester digester = new Digester();

digester.setValidating(false);

//完整類名定義,包名改變時需做相應變化

digester.addObjectCreate("foo", "org.easev.digester.Foo");

digester.addSetProperties("foo");

digester.addObjectCreate("foo/bar", "org.easev.digester.Bar");

digester.addSetProperties("foo/bar");

digester.addSetNext("foo/bar", "addBar", "org.easev.digester.Bar");

Foo foo = (Foo) digester.parse(input);

//測試裝載是否成功

Iterator iter = foo.getBars();

while (iter.hasNext()) {

System.out.println((String) iter.next());

}

}

}

匹配模式沒有什麼文章好做,那么下面要討論的就必然是規則了。在基本的使用方式下,Digester雖然使用XML檔案定義Java對象的狀態,提高了系統的靈活性,但是匹配模式與規則的映射序列(裝載邏輯)仍然通過硬編碼來定義,這種方式不易修改與重用。所以Digester還提供了一種高級的使用方式,用一個XML檔案定義Java對象的狀態(數據源檔案),用另一個XML檔案定義裝載數據源檔案的裝載邏輯。

這樣,對象的裝載過程分成了兩步:

1.裝載邏輯的"裝載",其結果表現為定義了rule的Digester;

2.根據上一步得到的Digester,裝載目標對象。

套用上面的一個例子,增加了rule.xml,並改寫了Entry.java

【rule.xml】

<?xml version="1.0"?>

<!DOCTYPE digester-rules

PUBLIC "-//Jakarta Apache //DTD digester-rules XML V1.0//EN"

"file:///../digester/dtds/digester-rules.dtd">

<digester-rules>

<pattern value="foo">

<object-create-rule classname="org.easev.digester.Foo"/>

<set-properties-rule/>

<pattern value="bar">

<object-create-rule classname="org.easev.digester.Bar"/>

<set-properties-rule/>

<set-next-rule methodname="addBar"/>

</pattern>

</pattern>

</digester-rules>

【Entry.java】

package org.easev.digester;

import java.io.File;

import java.util.Iterator;

import org.apache.commons.digester.Digester;

public class Entry {

public static void main(String[] args) throws Exception {

//相對路徑定義與包名相關

File data = new File("org/easev/digester/foo.xml");

File rule = new File("org/easev/digester/rule.xml");

Digester digester = DigesterLoader.createDigester(rule.toURL());

Foo foo = (Foo) digester.parse(data);

//測試裝載是否成功

Iterator iter = foo.getBars();

while (iter.hasNext()) {

System.out.println((String) iter.next());

}

}

}

我們可以看到,使用Digester的代碼變得相當簡潔,而要付出的代價就是為裝載邏輯寫一個配置檔案。

除了Digester之外,當然還有其它的方法來實現Java對象的綁定與裝載:

1.java.util.Properties,簡單的配置屬性(比如資料庫連線信息),可以寫在properties檔案中,調用Properties對象的load(InputStream)方法將配置中的健值對載入到Properties對象中。這種方式一般僅適用於簡單的配置信息的載入。

2.JAXB,Java Architecture for XML Binding,在Java Web Services Developer Pack V 1.1中提供了一個參考實現。使用這種方式時,除了提供數據源XML檔案之外,還必須提供相應的Schema檔案。載入前,首先用Binding Compiler將Schema轉換得到目標Java類的接口與實現,然後再調用Unmarshaller或Marshaller將數據源XML檔案信息載入到Java對象中,或將設定的Java對象數據導出為XML檔案。

3.XPath

4.JaxMe

套用項目

Tomcat

相關詞條

相關搜尋

熱門詞條

聯絡我們