java&XML學(xué)習(xí)第三天,cocoon2
首先,關(guān)于cocoon入門的資料網(wǎng)上比較少,一個(gè)是ibm上提供的三個(gè)cocoon的教程,比較不錯(cuò),另外就是cocoon自己的文檔,還有就是必須研究cocoon的源代碼了。
一、cocoon是什么?
按照我的理解,cocoon是一個(gè)整套的java web開發(fā)框架,象struts里面可以實(shí)現(xiàn)的功能,在cocoon里面其實(shí)都可以實(shí)現(xiàn),但是,我覺得他的側(cè)重點(diǎn)應(yīng)該是用于在web以各種樣式上發(fā)布xml內(nèi)容(Html,pdf,SVG),他提供了內(nèi)容、邏輯、表現(xiàn)在很大程度上的分離,這一點(diǎn)不是struts這種MVC框架的強(qiáng)項(xiàng)。
至于說有人將cocoon和struts進(jìn)行比較,我覺得應(yīng)該是不恰當(dāng)?shù)?,因?yàn)閮烧咧亟鉀Q的問題是不同的,如果你是一個(gè)新聞網(wǎng)站,以發(fā)布內(nèi)容為主,那么你可以考慮cocoon,但是如果你是一個(gè)信息管理系統(tǒng),側(cè)重于事物的處理,那么你可以選擇struts以及webwork2等框架。
二、cocoon能干什么?
- 提供靜態(tài)文件和動(dòng)態(tài)生成的響應(yīng)
- 使用任意數(shù)量的處理將用戶請求透明地映射到物理資源
- 執(zhí)行簡單和多級(jí) XSLT 轉(zhuǎn)換
- 將參數(shù)動(dòng)態(tài)傳遞到 XSLT 變換
- 生成各種各樣的輸出格式,包括 XML、HTML、PNG、JPEG、SVG 和 PDF
以上是ibm教程上的原話,可能只有最后的一條比較容易理解,不過希望您在讀完本文以后可以對上述的特性都有一個(gè)大概的理解。
三、為什么是cocoon 2?
cocoon1和cocoon2是cocoon的兩個(gè)不同的版本,其主要的區(qū)別是cocoon1是圍繞dom接口開發(fā)的,這是一種效率較低的api,而cocoon2是圍繞sax的。所以在學(xué)習(xí)cocoon2之前,建議了解sax和xml的相關(guān)知識(shí)。
四、開始進(jìn)入cocoon 2的世界,管道模型
安裝配置就不說了,網(wǎng)上可以找到相應(yīng)的說明,而且熟悉java web的人應(yīng)該可以知道如何安裝。
下面就說一說cocoon 2里面最重要的一個(gè)概念:管道
一個(gè)管道是由一個(gè)輸入開始,一個(gè)輸出結(jié)束,其中您可以加入任意多的對輸入數(shù)據(jù)的處理模塊。所以,在cocoon 2中,一個(gè)管道應(yīng)該是1輸入+n處理+1輸出。所有這些模塊,在cocoon中被稱為“components”。
下面是cocoon 2中內(nèi)置的幾個(gè)較為常用的模塊:
管道輸入 — 生成器(如FileGenerator,HTMLGenerator,DirectoryGenerator)和閱讀器(常用來讀靜態(tài)文件)
處理步驟 — 轉(zhuǎn)換器(如XSLT 轉(zhuǎn)換器)和操作
管道輸出 — 序列化器(如XML,HTML,SVG,PDF序列化器 )
條件的處理 — 匹配器和選擇器
cocoon的管道通常至少有生成器和序列化器,也就是我們說的輸入和輸出。這里面有個(gè)感念前面在學(xué)習(xí)xsl的時(shí)候提到過,就是對xml的轉(zhuǎn)換和格式化輸出是分開的,在cocoon里面很好的體現(xiàn)了這一點(diǎn)。
五、站點(diǎn)地圖
實(shí)際上,一個(gè)最簡單的管道應(yīng)該是使用匹配器來接受用戶請求(URL請求),使用生成器生成xml,使用各種轉(zhuǎn)換器,使用序列化器輸出。所有這些,將體現(xiàn)在cocoon的一個(gè)配置文件里面sitemap.xmap,就構(gòu)成了所謂的“站點(diǎn)地圖”。
下面是我做測試使用的站點(diǎn)地圖:

























































為了節(jié)省篇幅,我把后面的東西也放進(jìn)來,以后會(huì)慢慢解釋這個(gè)文件,先看圖中的(1),是所有的組件的定義。
(2)就是一個(gè)簡單的管道。從他的內(nèi)容可以看出,首先,他匹配welcome的用戶請求,假使是:http://localhost:8089/cocoon-dev/welcome,然后,有一個(gè)生成器,使用的是默認(rèn)的FileGenerator生成器,這個(gè)生成器將會(huì)讀取samples.xml文件,把它作為這個(gè)管道的輸入。
之后,有一個(gè)xsl的轉(zhuǎn)換器,他使用simple-samples2html.xsl來轉(zhuǎn)化生成器生成的xml,最后由一個(gè)html的序列化器生成輸出。simples.xml和simple-samples2html.xsl的代碼就不給出了,熟悉xml&xslt的朋友應(yīng)該明白。
在瀏覽器中輸入http://localhost:8089/cocoon-dev/welcome后就會(huì)得到輸出的html頁面。當(dāng)然,如果你將轉(zhuǎn)換器和序列化器的定義修改成:
<map:transform src="transforms/content2rss.xsl"/>
<map:serialize type="xml"/>
或者
<map:transform src="transforms/content2fo.xsl"/>
<map:serialize type="fo2pdf"/>
的話,你將會(huì)得到rss和pdf格式的輸出。個(gè)人認(rèn)為這應(yīng)該是cocoon的最主要的功能,這也是我了解cocoon的主要原因。
六、使用cocoon進(jìn)行開發(fā)
在cocoon 2的tutorial里面有這樣的一個(gè)章節(jié)介紹使用cocoon進(jìn)行web的開發(fā),但是其中只講到了自定義生成器的部分,個(gè)人認(rèn)為cocoon 2的建議是把查詢數(shù)據(jù)庫,邏輯運(yùn)算,商業(yè)邏輯等功能都放在生成器里面、xsp就是一種生成器他的寫法類似于jsp,但是不管是自定義的生成器還是xsp,其接口都比較復(fù)雜,我覺得并沒有struts來的方便,當(dāng)然這又回到了開始的話題,應(yīng)用的地方不同,沒有好壞之分,這里只是為了研究一下cocoon2的內(nèi)部結(jié)構(gòu)。
下面是一個(gè)自定義的生成器:











































第二點(diǎn)就是我們的generate方法里面寫的是sax事件的調(diào)用,也就是說,在執(zhí)行g(shù)enerate方法的時(shí)候,contentHandler就好像在讀取一個(gè)xml文件一樣。為了證明這一點(diǎn),我們有了管道中(3)的配置。運(yùn)行http://localhost:8089/cocoon-dev/heyThere之后,我們有了如下結(jié)果:


更進(jìn)一步的說,我們可以這樣理解,generate輸出一個(gè)xml,管道的下一個(gè)處理器接受到這個(gè)xml以后進(jìn)行一些操作,生成另外一個(gè)xml,以此類推,直到序列化器的出現(xiàn),把xml轉(zhuǎn)化成了想要的格式。這其實(shí)就是cocoon的基本工作原理。
七、實(shí)際原理
上面說的工作原理可以通過依次取掉generate后面的處理器,而在最后加裝xml的序列化器來驗(yàn)證,但是在cocoon的內(nèi)部,卻沒有什么xml被傳來傳去,那么管道的各個(gè)組件之間是怎樣協(xié)作的呢?在教程上有句話說是通過互相傳遞sax事件實(shí)現(xiàn)的,乍一聽來非常難以理解,經(jīng)過了無數(shù)次調(diào)試后,終于得知了實(shí)情。
我們來看如下的代碼:




















.......................


.......................






........................







而且,通過調(diào)試得知,每一個(gè)組件,不管是什么類型,都會(huì)有一個(gè)XMLConsumer的屬性,另外,還都會(huì)有一個(gè)contentHandler的屬性。ContentHandler這個(gè)類是標(biāo)準(zhǔn)的sax接口,從這一點(diǎn)分析,XMLConsumer有可能是cocoon1的殘留物,而真正在cocoon2里面其作用的是ContentHandler這個(gè)接口的一些實(shí)現(xiàn)類。
后面又進(jìn)行了一些調(diào)試,結(jié)果卻是驗(yàn)證了上面的說法,為了測試做了如下的配置:
<map:match pattern="welcome">
<map:generate type="helloWorld"/>
<map:transform src="simple-samples2html.xsl"/>
<map:transform src="simple-samples2html2.xsl"/>
<map:serialize type="xml"/>
</map:match>
結(jié)果是這樣的,自定義的generate類的generate()方法中的contentHandler.startDocument();一句的實(shí)現(xiàn)代碼如下:這段代碼在AbstractXMLPipe這個(gè)類中






generate的對象我們稱之為g1,
generate的contentHandler屬性就是TraxTransformer類的一個(gè)對象,也就是
<map:transform src="simple-samples2html.xsl"/>這一句的實(shí)現(xiàn)載體,我們暫且稱這之對象為t1,
而<map:transform src="simple-samples2html2.xsl"/>的實(shí)現(xiàn)載體對象我們暫稱之為t2,
<map:serialize type="xml"/>的實(shí)現(xiàn)載體是XMLSerializer類的一個(gè)對象,我們暫稱之為s1
他們之間的關(guān)系是g1.contentHandler = t1.contentHandler = t2.contentHandler = s1.contentHandler,而且所有的contentHandler都是AbstractXMLPipe這個(gè)類的某一個(gè)子類型,也就是說他們的startDocument()等方法的實(shí)現(xiàn)都是完全一樣的。
這樣一來,每一個(gè)sax的事件將會(huì)在generate.generate()方法中被開始調(diào)用,并不斷地遞歸g1,t1,t2.....s1,這就是cocoon管道之間各個(gè)組件互相傳遞數(shù)據(jù)的真相。
八、其他一些技術(shù)的了解:
cocoon中比較有用的一些技術(shù)還有xsp和esql,其中xsp是一個(gè)類似jsp的組件,他在cocoon中的地位應(yīng)該是一種generate,用來生成最初的xml,并且,他可以內(nèi)嵌java代碼,就像jsp那樣,取得request參數(shù),查詢數(shù)據(jù)庫等,如站點(diǎn)地圖中的(4)所示,我們可以把這樣的一個(gè)組件作為管道的起點(diǎn),這樣我們查詢或者業(yè)務(wù)處理的結(jié)果就可以通過管道被發(fā)布成各種樣式了!
下面給出一個(gè)xsp的簡單例子:






















esql是在xsp上使用的一項(xiàng)技術(shù),他應(yīng)該類似于jsp的一些標(biāo)簽庫,實(shí)現(xiàn)的功能是操作數(shù)據(jù)庫,直接寫在xsp文件中的,這樣可以很方便的生成一個(gè)由數(shù)據(jù)庫驅(qū)動(dòng)的動(dòng)態(tài)的xml,配合上cocoon的其他組件,也就是說可以很方便的把數(shù)據(jù)庫中的東西發(fā)布成各種版本。
下面是他的一些語法定義:
































九、struts&cocoon
目前,已經(jīng)有人想到了struts和cocoon的整合,用struts來處理邏輯層的事物,用cocoon來實(shí)現(xiàn)多種表現(xiàn)形式,操作方法大概提供一個(gè)struts的plugin,可以把struts最終的jsp作為cocoon的xml源來使用。
地址:http://struts.sourceforge.net/struts-cocoon/
不過個(gè)人認(rèn)為這種結(jié)合的方式還是比較生硬,記得以前看到過關(guān)于strutsX的有關(guān)介紹,希望這種事物處理層和表現(xiàn)層同樣強(qiáng)大的框架可以早點(diǎn)出來,順便說一句,cocoon 2項(xiàng)目以前是屬于apache xml項(xiàng)目下的,現(xiàn)在已經(jīng)是一個(gè)獨(dú)立的項(xiàng)目http://cocoon.apache.org,在這里也祝愿cocoon能夠飛的更高,飛得更遠(yuǎn)。
第一次寫那么多,試試發(fā)布一下,純粹是可望志同道合的人交流,各位高手見笑了^_^
posted on 2005-03-10 15:38 Boris-Java 閱讀(2178) 評論(2) 編輯 收藏 所屬分類: java&xml