(文章轉自CSDN)
如果你不熟悉Jakarta Commons話,那么很有可能你已經重新發明了好幾個輪子。在你編寫更多的普通的框架或工具之前,體驗一下Commons吧。它將會大大地節約你的時間。太多的人自己寫一個,其實是與Commons Lang中的StringUtils重復的StringUtils類,或者,開發者不知道從Commons Collections中重新創建工具,哪怕commons-collections.jar已經在classpath中可用了。
真的,請停一下。看看Commons Collections API,然后再回到你的任務中;我發誓你會發現一些簡單有用的東西可以幫你在明年節省一周的時間。如果大家花一點時間看看Jakarta Commons,我們將會得到更少的重復代碼—我們將在重用的宗旨下真正做一些有用的事情。
我確實看到這樣的情況發生過:一些人研究了一下Commons BeanUtils或者Commons Collections,然后總是有“啊,如果我那時知道這個的話,我就不會寫那一萬行的代碼了”這樣的時刻。Jakarta Commons仍有一部分保持相當的神秘;比如,許多人還沒有聽說過Commons CLI和Commons Configuration,并且大多數人還沒有注意到Commons Collections中的functors(算子)包的價值。在這一系列中,我會專門強調一些Jakarta Commons中較少得到重視的工具和功能。
在這一系列的第一部分,我將探索定義在Commons Digester中的XML規則,Commons Collections中的功能,和使用一個有趣的應用,Commons JXPath,來查詢一個對象的List。Jakarta Commons包含的功能目的在于幫助你解決低層次的編程問題:遍歷集合,解析XML和從List中檢出對象。我建議你花一些時間在這些小功能上,學習Jakarta Commons真的會為你節省不少時間。
并不簡單地是學習使用Commons Digester來解析XML或者使用CollectionUtils的Predicate來過濾一個集合,而是當你一旦意識到如何將這些功能組合起來使用并且如何將Commons集成到你的項目中去的時候,你才會真正地看到它的好處。如果你這樣做地話,你將會把commons-lang.jar, commons-beanutils.jar,和 commons-digester.jar當成JVM本身來看待。
如果你對Jakarta Commons更深的內容感興趣的話,可以看一下Jakarta Commons Cookbook。這本書給你很多方法來更好的使用Commons,并告訴你如何將Jakarta Commons與其它的小的開源組件集成,如Velocity, FreeMarker, Lucene, 和 Jakarta Slide。這本書,我介紹了一組廣泛的工具從Commons Lang中的簡單工具到組合了Commons Digester, Commons Collections, 和Jakarta Lucene來搜索威廉.莎士比亞的著作。我希望這一系列和Jakarta Commons Cookbook這本書能夠提供給你一些有趣的低層次的編程問題的解決方案。
1. 用于Commons Digester的基于XML的規則集
Commons Digester 1.6提供了將XML轉化為對象的最簡單的方法。Digester已經由O'Reilly網站上的兩篇文章介紹過了:“學習和使用Jakarta Digester”,作者是Philipp K. Janert,和“使用Jakarta Commons, 第二部分”,作者是Vikram Goyal。兩篇文章都演示了XML規則集的使用,但如何在XML中定義規則集并沒有理解。大多所見到的Digester的使用是程序化地定義規則集,以已編譯的形式。你應該避免硬編碼的Digester規則,特別是當你可以將映射信息存儲在外部文件中或一個類路徑資源中時。外部化一個Digester規則可以更好地適應一個演化中的XML文檔結構或者說一個演化中的對象模型。
為了演示在XML中定義規則集與硬編碼的規則集之間的區別,考慮系統解析XML給一個Person bean,包括在下面定義的屬性—id, name和age。
package org.test;
public class Person {
public String id;
public String name;
public int age;
public Person() {}
public String getId() { return id; }
public void setId(String id) {
this.id = id;
}
public String getName() { return name; }
public void setName(String name) {
this.name = name;
}
public int getAge() { return age; }
public void setAge(int age) {
this.age = age;
}
}
確認你的應用需要解析一個包含了多個person元素的XML文件。下面的XML文件,data.xml,包含了兩個person元素,你想要把它們解析到Person對象中:
Tom Higgins
25
Barney Smith
75
Susan Shields
53
你希望如果結構和XML文件的內容在未來幾個月中變化,你不需要在已編譯的Java代碼中硬編碼XML文件的結構。為了做到這一點,你需要在一個XML文件中定義Digester的規則,并且它可以作為一種資源從類路徑中裝入。下面的XML文檔,person-rules.xml,映射person元素到Person bean:
paramtype="java.lang.Object"/>
上述所做的是指示Digester創建一個新的Person實例,當它遇到一個person元素時,調用add()來將Person對象加入到一個ArrayList中,設置person元素中相匹配的屬性,并從下一級元素name和age中設置name和age的屬性。
現在你已經看到了Person類,會被解析的文檔,和以XML的形式定義的Digester規則。現在你需要創建一個由person-rules.xml定義了規則的Digester的實例。下面的代碼創建 了一個Digester,通過將person-rules.xml的URL傳遞給DigesterLoader
既然person-rules.xml文件是與解析它的類在同一個包內的類路徑資源,URL可以通過getClass().getResource()來得到。DigesterLoader然后解析規則并將它加到新創建的Digester上:
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
// 從XML規則集中配置Digester
URL rules = getClass().getResource("./person-rules.xml");
Digester digester =
DigesterLoader.createDigester(rules);
// 將空的List推入到Digester的堆棧
List people = new ArrayList();
digester.push( people );
// 解析XML文檔
InputStream input = new FileInputStream( "data.xml" );
digester.parse( input );
一旦Digester完成對data.xml的解析,三個Person對象將會在ArrayList people中。
與將規則定義在XML不同的方法是使用簡便的方法將它們加入到一個Digester實例中。大多數文章和例子都用這種方法,使用addObjectCreate() 和 addBeanPropertySetter()這樣的方法來將規則加入中Digester上。下面的代碼加入了與定義在person-rules.xml中相同的規則:
digester.addObjectCreate("people/person", Person.class);
digester.addSetNext("people/person", "add", "java.lang.Object");
digester.addBeanPropertySetter("people/person", "name");
digester.addBeanPropertySetter("people/person", "age");
如果你曾經發現自己正在用一個有著2500行代碼的類,用SAX來解析一個巨大的XML文檔,或者使用DOM或JDOM的完整的一個集合類,你就會理解XML的解析比它應該做的要復雜的多,就大多數情況來說。如果你正在建一個有著嚴格的速度和內存要求的高效的系統,你會需要SAX解析器的速度。如果你需要DOM級別3的復雜度,你會需要像Apache Xerces的解析器。但如果你只是簡單的試圖將幾個XML文檔解析到對象中去的話,看一下Commons Digester, 并把你的規則定義在一個XML文件中。
任何時候你都應該將配置信息從硬編碼中移出來。我會建議你在一個XML文件中定義規則并從文件系統或類路徑中裝入它。這樣可以使你的程序更好地適應XML文檔以及對象模型的變化。有關在XML文件中定義Digester規則的更多的資料,參看Jakarta Commons Cookbook一書的6.2節,“將XML文檔轉換為對象”
>>>>下一章