日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

利用Digester把XML轉(zhuǎn)換為Java對象

 CevenCheng 2011-07-23

在一個比較完整的應(yīng)用系統(tǒng)里,經(jīng)常需要有一些配置文件。簡單的屬性使用.properties文件即可,但要配置一些復(fù)雜對象,則應(yīng)該考慮使用xml文件。一般用來讀取xml文件的工具包有DOM、SAX和JDOM等,但用過的人都知道,它們屬于比較底層的API,寫起來代碼量很大,而且如果修改了xml文件的格式,代碼也要做大幅度的改動。Jakarta Commons項目里的Digester包,可以輕松實現(xiàn)xml文件到Java對象的轉(zhuǎn)換,看下面這個例子。

在一個項目里,需要提供一些統(tǒng)計圖,但圖的內(nèi)容暫時未能確定。所以我決定讓圖可以配置,所有定義保存在一個名為charts.xml(或國際化后的文件名如charts_zh_CN.xml,這里只考慮缺省語言)的文件內(nèi),下面是該文件的部分內(nèi)容:

 

<?xml version="1.0" encoding="UTF-8" ?>
<charts>
    
<chart id="BarChart1" >
        
<title>統(tǒng)計圖一</title>
        
<legendVisible>false</legendVisible>
        
<toolTipsVisible>true</toolTipsVisible>
        
<type>Bar</type>
        
<labelx>時間</labelx>
        
<labely>數(shù)據(jù)</labely>
        
<width>500</width>
        
<height>360</height>
        
<hql>select count(c),c.department.name from edu.pku.pub.aims.model.business.Client c group by c.department</hql>
        
<description></description>
    
</chart>
</charts>

可以看出,我為每個圖定義了id、title、legendVisible等等屬性,這些屬性的意義都很明顯,它們將影響統(tǒng)計圖的數(shù)據(jù)和在頁面中的表現(xiàn)。在程序里,我需要把這個文件里的定義讀到一個注冊表類ChartRegistry里,該注冊表維護(hù)一個java.util.List類型的registry變量,其中每個元素是一個ChartConfig類。現(xiàn)在Digester該顯示它的價值了。

為了方便使用Digester,我們讓ChartConfig也具有統(tǒng)計圖的每個屬性(id、title、legendVisible等等),名稱與charts.xml里的元素的屬性(子元素)一一對應(yīng),并且都具有g(shù)etter和setter方法,也就是說,ChartConfig是一個bean類。在ChartRegistry類里定義一個deregister()方法,它的作用是用Digester讀入并解析指定的xml文件,代碼如下;還有一個register()方法用來把ChartConfig對象加到registry里。

 

public void deregister(URL url) throws IOException,SAXException{
    InputStream is 
= new FileInputStream(url.getFile());
    Digester digester 
= new Digester();
    digester.push(
this);
    digester.setValidating(
false);
    digester.addObjectCreate(
"charts/chart", ChartConfig.class);
    digester.addSetProperties(
"charts/chart");
    digester.addBeanPropertySetter(
"charts/chart/legendVisible");
    digester.addBeanPropertySetter(
"charts/chart/toolTipsVisible");
    digester.addBeanPropertySetter(
"charts/chart/title");
    digester.addBeanPropertySetter(
"charts/chart/type");
    digester.addBeanPropertySetter(
"charts/chart/labelx");
    digester.addBeanPropertySetter(
"charts/chart/labely");
    digester.addBeanPropertySetter(
"charts/chart/width");
    digester.addBeanPropertySetter(
"charts/chart/height");
    digester.addBeanPropertySetter(
"charts/chart/hql");
    digester.addBeanPropertySetter(
"charts/chart/description");
    digester.addSetNext(
"charts/chart","register");
    digester.parse(is);
    Collections.sort(registry);
}

基本上來說,Digester和SAX解析xml的過程很像,它的原理就是制定一些規(guī)則,在遍歷每個節(jié)點時檢查是否有匹配的規(guī)則,如果有就執(zhí)行對應(yīng)的操作。例如,上面的代碼中,“digester.addObjectCreate("charts/chart", ChartConfig.class);”這一句的作用是告訴Digester:如果遇到匹配“charts/chart”形式的節(jié)點,就執(zhí)行一個“對象創(chuàng)建”操作,創(chuàng)建什么對象呢,應(yīng)該創(chuàng)建Class為“ChartConfig.class”的對象;類似的,addSetProperties()是告訴Digester將指定節(jié)點的屬性全部映射到對象的屬性,在這個例子里指的就是id屬性;addBeanPropertySetter()是將子節(jié)點轉(zhuǎn)換為對象的屬性,這個方法還可以有第二個參數(shù),當(dāng)對象的屬性名和子節(jié)點的名字不一樣時用來指定對象的屬性名;addSetNext()是說在遇到匹配節(jié)點后,對當(dāng)前對象的父對象執(zhí)行一個方法,參數(shù)是當(dāng)前參數(shù),對這個例子來說就是執(zhí)行ChartConfig.register(ChartConfig)方法。因此這樣構(gòu)造得到的Digester會把charts.xml里的每個元素轉(zhuǎn)換為一個ChartConfig對象,并register到ChartRegistry里。

順利得到了ChartRegister對象,我就可以在程序里根據(jù)它的內(nèi)容構(gòu)造統(tǒng)計圖了(統(tǒng)計圖一般使用jfreechart來生成,這里就不贅述了)。與Digester具有類似功能的工具包其實還有不少,例如Caster、Jato等等,我沒有實際使用過它們,但因為我對用過的Jakarta其他項目都很滿意(例如BeanUtils、HttpClient,品牌效應(yīng)?),所以一開始就選擇了Digester:簡單方便。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多