cocoon系列——開(kāi)發(fā)一個(gè)Web站點(diǎn)
Cocoon 2 引入了這些數(shù)據(jù)庫(kù)集成功能,但它并沒(méi)有被設(shè)計(jì)成完整的 Java 應(yīng)用程序服務(wù)器框架。Cocoon 2 不與基于 J2EE 體系結(jié)構(gòu)的服務(wù)器競(jìng)爭(zhēng),因?yàn)樗鼪](méi)有提供同等級(jí)別的資源和事務(wù)管理、負(fù)載均衡和部署選項(xiàng)。Cocoon 2 最適合于少量復(fù)雜業(yè)務(wù)邏輯和處理主要用于內(nèi)容生成的應(yīng)用程序。然而,您仍然可以和 EJB 服務(wù)器一起使用 Cocoon 2。Cocoon 2 可以輕易地充當(dāng)替換表示層,而更常用的 Java Servlet 和 Java Server Pages 則要遜色得多。簡(jiǎn)而言之,Cocoon 2 旨在通過(guò)從少量的功能提供最大的靈活性來(lái)滿足 80/20 規(guī)則。
一、配置DB連接
1.1、web.xml
<init-param>
<param-name>extra-classpath</param-name>
<param-value>WEB-INF/extra-classes1:/ABSOLUTE-PATH-TO-ARCHIVE</param-value>
</init-param>
或者直接將jdbc驅(qū)動(dòng)扔到tomcat的common\lib中
<init-param>
<param-name>load-class</param-name>
<param-value>
com.mysql.jdbc.Driver
</param-value>
</init-param>
1.2、cocoon.xconf中加:
<datasources>
……
<jdbc logger="core.datasources.personnel" name="ldodds">
<pool-controller max="10" min="5"/>
<dburl>jdbc:mysql://localhost:3306/new_db?autoReconnect=true</dburl>
<user>root</user>
<password>bibi</password>
</jdbc>
……
</datasources>
二、ESQL 邏輯表
ESQL 邏輯表是標(biāo)準(zhǔn) JDBC API 上較“瘦”的一層,它定義了許多映射到特定 JDBC 功能的標(biāo)記。因此,邏輯表是一種為應(yīng)用程序生成 JDBC 代碼的簡(jiǎn)單方法。使用 ESQL 邏輯表時(shí),必須使用許多常用結(jié)構(gòu)化元素。其中每個(gè)元素都從 JDBC API 中等價(jià)的對(duì)象中派生出它的功能。在所有情況下,您都可以將 ESQL 標(biāo)記同那些由 XSP 頁(yè)面直接輸出的用戶定義標(biāo)記混合在一起。您也可以使用 XSP 標(biāo)記和來(lái)自其它邏輯表的標(biāo)記,來(lái)定義所需的額外處理。唯一真正的限制是要確保 XSP 頁(yè)面保持格式良好。
2.1、esql:connection
esql:connection
等價(jià)于 JDBC Connection。
正如所有 JDBC 操作最終都派生自特殊的數(shù)據(jù)庫(kù)連接一樣,必需將每個(gè) ESQL 元素都適當(dāng)?shù)厍短自?esql:connection
元素內(nèi)。在單個(gè) XSP 頁(yè)面內(nèi)具有多個(gè)連接元素是可能的,這樣就允許單個(gè)頁(yè)面同多個(gè)數(shù)據(jù)源交互。連接元素還必須包含定義如何創(chuàng)建數(shù)據(jù)庫(kù)連接的其它元素(例如,esql:pool
)。
第一種方法是簡(jiǎn)單地引用以前定義的連接池,使用 esql:pool
元素實(shí)現(xiàn)這一點(diǎn):
<esql:connection>
<esql:execute-query>
<esql:pool>myPoolName</esql:pool>
...
</esql:execute-query>
</esql:connection>
第二種方法是直接在 esql:connection
元素內(nèi)定義連接參數(shù)。使用下列元素來(lái)實(shí)現(xiàn)這一點(diǎn):
esql:dburl
— JDBC 連接字符串
esql:username
— 連接到數(shù)據(jù)庫(kù)的用戶名
esql:password
— 以上用戶名的密碼
esql:driver
— JDBC 驅(qū)動(dòng)程序
esql:autocommit
— 指出應(yīng)當(dāng)自動(dòng)提交 JDBC 連接
后一種方法的優(yōu)點(diǎn)在于可以動(dòng)態(tài)生成連接詳細(xì)信息 — 例如,從當(dāng)前會(huì)話檢索用戶名和密碼。雖然這樣做提供了極大程度的靈活性,但是也喪失了通過(guò)使用數(shù)據(jù)庫(kù)池讓 Cocoon 管理連接的性能優(yōu)點(diǎn)。
因此,除非需要這一動(dòng)態(tài)行為,否則就建議使用 esql:pool
元素定義連接。
2.2、esql:execute-query
esql:execute-query
元素等價(jià)于 JDBC PreparedStatement
對(duì)象。它定義如何在給定數(shù)據(jù)庫(kù)連接內(nèi)執(zhí)行個(gè)別查詢以及應(yīng)該如何處理這些查詢的結(jié)果。嵌套個(gè)別 esql:execute-query
元素以創(chuàng)建嵌套的數(shù)據(jù)庫(kù)查詢是可接受的。
2.3、esql:query
esql:query
元素含有將要使用這一連接執(zhí)行的 SQL 查詢(SELECT、INSERT、UPDATE 或 DELETE)。對(duì)查詢結(jié)果的處理取決于執(zhí)行的查詢類型。對(duì) SELECT 語(yǔ)句的處理定義在 esql:results
元素內(nèi),而 INSERT、UPDATE 和 DELETE 的結(jié)果則在 esql:update-results
元素內(nèi)處理。
<esql:query>
select cat_id, name from category
order by cat_id
</esql:query>
2.4、esql:row-results
使用 esql:row-results
元素來(lái)定義如何處理查詢結(jié)果中的每一行,該元素是 esql:results
的子元素。該元素的內(nèi)容被轉(zhuǎn)換成由查詢生成的 JDBC ResultSet
中的每一行都執(zhí)行的代碼。
<esql:results>
<esql:row-results>
<category>
<esql:get-columns/>
</category>
</esql:row-results>
</esql:results>
產(chǎn)生下列輸出:
<categories>
<category>
<CAT_ID>1</CAT_ID><NAME>Blues</NAME>
</category>
...more results...
</categories>
2.5、讀方法(getter) 元素
<esql:results>
<esql:row-results>
<category>
...xsp:attribute elements as before...
<xsp:logic>
if (<esql:get-int column="cat_id"/> % 2 == 0)
{
<xsp:attribute name="rowtype">even</xsp:attribute>
}
else
{
<xsp:attribute name="rowtype">odd</xsp:attribute>
}
</xsp:logic>
</category>
</esql:row-results>
</esql:results>
2.6、其它數(shù)據(jù)操作元素
esql:get-column-count
— 返回結(jié)果中列的數(shù)目。請(qǐng)?jiān)谛枰错樞蛱幚砹械牡胤绞褂迷撛貋?lái)建立循環(huán)。
esql:get-metadata
— 返回對(duì) ResultSetMetadata
的引用。
esql:get-resultset
— 返回對(duì) JDBC ResultSet
的引用以供直接操作。
esql:get-row-position
— 獲取結(jié)果中當(dāng)前行的位置。請(qǐng)使用該元素來(lái)提供表的行數(shù)等功能。
esql:get-column-name
— 獲取當(dāng)前列的名稱,必須用該列的位置來(lái)引用該列。在按順序處理結(jié)果集中的列時(shí),請(qǐng)使用該元素。
esql:is-null
— 測(cè)試給定列是否具有 NULL 值。
esql:get-xml
— 添加由 JDBC ResultSet
提供的功能。檢索指定列的值并將其作為 XML 解析。在解析之前,可以有選擇地將列的值封裝在另一個(gè)元素(由 root
屬性指定)中。在原始 XML 數(shù)據(jù)存放在數(shù)據(jù)庫(kù)中時(shí),請(qǐng)使用該元素。
2.7、處理空結(jié)果和錯(cuò)誤
前面的這些示例假定查詢總是成功完成并且總是返回結(jié)果。顯然,事情并不總是這樣的:有些查詢可能不返回?cái)?shù)據(jù),也可能發(fā)生數(shù)據(jù)庫(kù)錯(cuò)誤(例如,由于連接故障)。ESQL 邏輯表提供允許您處理這些情形的標(biāo)記。
如果查詢不返回結(jié)果,那么可以通過(guò)使用 esql:no-rows
元素來(lái)采取行動(dòng)。
...
<esql:results><results/></esql:results>
<esql:no-results><no-results/></esql:no-results>
...
esql:error-results
元素為處理 SQLException
提供了一個(gè)鉤接(hook),該異常是在處理查詢結(jié)果期間生成的。
...
<esql:error-results>
<error>
<message><esql:get-message/></message>
<trace><esql:get-stacktrace/></trace>
<string><esql:to-string/></string>
</error>
</esql:error-results>
...
將處理結(jié)果時(shí)發(fā)生的異常情形同創(chuàng)建數(shù)據(jù)庫(kù)連接或查詢包含語(yǔ)法錯(cuò)誤時(shí)發(fā)生的異常情形區(qū)分開(kāi)來(lái)非常重要。這些更嚴(yán)重的錯(cuò)誤并不傳遞給 XSP 頁(yè)面,而是由 Cocoon 2 自身處理。
2.8、將參數(shù)傳遞給查詢
<esql:query>
select * from album
where cat_id = <xsp-request:get-parameter name="id"/>
</esql:query>
2.9、嵌套查詢
<esql:connection>
<esql:execute-query>
<esql:query/>
<esql:results>
<!-- results from query
one -->
<esql:execute-query>
<esql:query/>
<esql:results>
<!-- results from query
two -->
</esql:results>
</esql:execute-query>
</esql:results>
</esql:execute-query>
</esql:connection>
內(nèi)部查詢引入了一段新 ESQL 語(yǔ)法:
<esql:query>
select alb_id as id, title, artist,
num_tracks as tracks
from album
where cat_id = <esql:get-int column="cat_id" ancestor="1"/>
</esql:query>
在查詢的 WHERE 子句中,esql:get-int
元素用于檢索外部查詢的當(dāng)前類別值。新的 ancestor
元素指示從哪個(gè)外面查詢檢索該值 — 例如同第一個(gè) esql:execute-query
ancestor 元素相關(guān)聯(lián)的結(jié)果。
2.10、分組數(shù)據(jù)
esql:group
和 esql:member
元素可以利用表連接結(jié)果中的這些模式來(lái)將相關(guān)記錄整理在一起。esql:group
元素具有 group-on
屬性。該屬性標(biāo)識(shí)結(jié)果中可以用來(lái)區(qū)別外部元素(換句話就是類別)的列。元素的內(nèi)容定義將對(duì)每個(gè)不同類別采用的處理,而不是定義對(duì)結(jié)果的每一行的處理。esql:member
元素定義對(duì)共享由 group-on
屬性定義的公共列的每一行的處理。這里,該元素含有建立每個(gè)專輯的 XML 結(jié)構(gòu)所需的處理,最終的 XML 結(jié)構(gòu)與嵌套查詢版本生成的結(jié)構(gòu)相同。
<esql:row-results>
<esql:group group-on="cat_id">
<category>
<!-- process category data -->
<albums>
<esql:member>
<album>
<!-- process album data -->
<id><esql:get-string column="alb_id"/></id>
</album>
</esql:member>
</albums>
</category>
</esql:group>
</esql:row-results>
三、表單驗(yàn)證
3.1描述表單
下面的示例演示了用于描述表單字段、由 Form Validator Action 所支持的 XML 格式的基本語(yǔ)法。
<root>
<!-- field definitions -->
<parameter name="id" type="long"
min="1" max="99999" nullable="no"/>
<parameter name="cat" type="long"
min="1" max="999" nullable="no"/>
<parameter name="title" type="string"
max-len="100" nullable="no"/>
<parameter name="artist" type="string"
max-len="100" nullable="no"/>
<parameter name="tracks" type="long"
max="99" nullable="no"/>
<constraint-set
name="insert-album">
<validate name="id"/>
<validate name="cat"/>
<validate name="title"/>
<validate name="artist"/>
<validate name="tracks"/>
</constraint-set>
</root>
說(shuō)明:首先,忽略了文檔的根元素,因此它可以具有任何名稱。第二,文檔被分成了兩部分:許多字段定義后跟約束集。
每個(gè)字段定義都描述了用戶提交的參數(shù)。參數(shù)都必須有唯一的 name
屬性。字段還必須有類型,類型可以是下列之一:long
、double
或 string
。每個(gè)字段接下來(lái)可以定義許多指定為附加屬性的驗(yàn)證規(guī)則:
nullable
— 標(biāo)識(shí)字段是否可為空
default
— 如果沒(méi)有為字段提供值,則標(biāo)識(shí)字段的缺省值
min
和 max
— 表示最小和最大值
min-len
和 max-len
— 表示最小和最大長(zhǎng)度
matches-regex
— 定義一個(gè)必須正確匹配參數(shù)值的 POSIX 正則表達(dá)式;這允許更豐富的內(nèi)容驗(yàn)證,例如電子郵件地址格式
約束集描述了預(yù)定義字段的組合,對(duì)這些字段進(jìn)行驗(yàn)證將一遍完成,如下面所描述。約束集中的 validate
元素支持兩種附加屬性:
equals-to
— 定義參數(shù)必須匹配的固定字符串
equals-to-param
— 定義另一個(gè)應(yīng)該具有相同值的參數(shù)的名稱,該參數(shù)可以完成一些功能,例如檢查用戶是否在一個(gè)驗(yàn)證新密碼的表單上兩次都輸入了相同的密碼。
3.2、驗(yàn)證字段
3.2.1站點(diǎn)地圖中對(duì)它加以聲明
同任何其它 Cocoon 2 組件一樣,在可以使用 Form Validator Action 以前,必須首先在站點(diǎn)地圖中對(duì)它加以聲明:
<map:components>
...
<map:actions>
<map:action name="form-validator"
src="org.apache.cocoon.acting.FormValidatorAction"/>
</map:actions>
...
</map:components>
3.2.2向 Cocoon 2 管道添加操作
<map:match pattern="form/insert-album">
<map:act type="form-validator">
<map:parameter name="descriptor"
value="context://insert-album.xml"/>
<map:parameter name="validate-set"
value="insert-album"/>
<!-- if success -->
...
</map:act>
<!-- if fail -->
...
</map:match>
如果驗(yàn)證成功,則處理 map:act
元素內(nèi)的其它管道組件。就是在這里調(diào)用 insert-album.xsp
,XSP 頁(yè)面以插入已知有效的數(shù)據(jù)。
如果驗(yàn)證不成功,則只執(zhí)行 map:act
元素后面的組件。這樣,Actions 的行為類似于“if”語(yǔ)句:如果它們成功地執(zhí)行了它們的處理,那么將執(zhí)行嵌套在它們之內(nèi)的管道組件塊;否則,就跳過(guò)該塊。
3.2.3、使用 Form Validator 邏輯表
您只可以將 Form Validator 邏輯表同 Form Validator Action 一起使用。該邏輯表通常在 XSP 頁(yè)面內(nèi)使用,如果表單未能被驗(yàn)證,就執(zhí)行該頁(yè)面。操作將其結(jié)果的詳細(xì)分解作為 HTTP 請(qǐng)求參數(shù)存儲(chǔ)。這一邏輯表為解釋這些結(jié)果提供了一個(gè)簡(jiǎn)單的基于標(biāo)記的 API。
這一邏輯表的名稱空間是 http://apache.org/xsp/form-validator/2.0
。
下列來(lái)自邏輯表的每一元素都接受 name
屬性,該屬性表示正在測(cè)試驗(yàn)證狀態(tài)的字段的名稱。
formval:is-ok
— 返回一個(gè)指示字段驗(yàn)證是否成功的布爾值
formval:is-null
— 在字段本不該為空時(shí)表示該字段為空
formval:is-toosmall
— 表示字段長(zhǎng)度比 min-len
短或值比 min
小
formval:is-toolarge
— 表示字段長(zhǎng)度比 max-len
長(zhǎng)或值比 max
大
formval:is-nomatch
— 表示字段未能匹配所配置的正則表達(dá)式
Q : org.apache.avalon.framework.configuration.ConfigurationException: No default type exists for 'pipeline' at file:/C:/code/tech/web/sitemap.xmap………
A: The samples sitemaps are sub sitemaps and inherit the pipelines configuration form the root sitemap. Their you will find a map:pipes with a default type configured.
Q: Caused by: org.xml.sax.SAXParseException: The reference to entity "password" must end with the ';' delimiter.
A: “ jdbc:mysql://192.168.0.1:3306/school?useUnicode=true&characterEncoding=GB2312 “ 中的"&"必須用它的轉(zhuǎn)義字符&
Q: Communication failure during handshake. Is there a server running on localhost:3306?
A: 嘗試下一個(gè)新版本的驅(qū)動(dòng):http://dev.mysql.com/downloads/
Class.forName("org.gjt.mm.mysql.Driver") 可以嘗試換成
Class.forName("com.mysql.jdbc.Driver")
PS: 暈菜,被這個(gè)問(wèn)題搞了兩個(gè)小時(shí)。在這之前mysql和jdbc連接一直是可以用的,不過(guò)前幾天升級(jí)了一下mysql,但版本差別不大,版本號(hào)前面都有一個(gè)5。另外因?yàn)槭堑谝淮卧赾ocoon配置,以為是配置文件搞錯(cuò)了,就在那里瞎折騰。到最后,才決定要看看究竟是不是mysql的JDBC驅(qū)動(dòng)版本引起的,就寫了一個(gè)簡(jiǎn)單的JSP測(cè)試頁(yè),結(jié)果竟然連接不成功,出現(xiàn)如上提示
posted on 2005-12-14 18:53
魚(yú)上游 閱讀(1767)
評(píng)論(0) 編輯 收藏 所屬分類:
爪哇世界探險(xiǎn)