cocoon系列——開發一個Web站點
Cocoon 2 引入了這些數據庫集成功能,但它并沒有被設計成完整的 Java 應用程序服務器框架。Cocoon 2 不與基于 J2EE 體系結構的服務器競爭,因為它沒有提供同等級別的資源和事務管理、負載均衡和部署選項。Cocoon 2 最適合于少量復雜業務邏輯和處理主要用于內容生成的應用程序。然而,您仍然可以和 EJB 服務器一起使用 Cocoon 2。Cocoon 2 可以輕易地充當替換表示層,而更常用的 Java Servlet 和 Java Server Pages 則要遜色得多。簡而言之,Cocoon 2 旨在通過從少量的功能提供最大的靈活性來滿足 80/20 規則。
一、配置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驅動扔到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 邏輯表是標準 JDBC API 上較“瘦”的一層,它定義了許多映射到特定 JDBC 功能的標記。因此,邏輯表是一種為應用程序生成 JDBC 代碼的簡單方法。使用 ESQL 邏輯表時,必須使用許多常用結構化元素。其中每個元素都從 JDBC API 中等價的對象中派生出它的功能。在所有情況下,您都可以將 ESQL 標記同那些由 XSP 頁面直接輸出的用戶定義標記混合在一起。您也可以使用 XSP 標記和來自其它邏輯表的標記,來定義所需的額外處理。唯一真正的限制是要確保 XSP 頁面保持格式良好。
2.1、esql:connection
esql:connection
等價于 JDBC Connection。
正如所有 JDBC 操作最終都派生自特殊的數據庫連接一樣,必需將每個 ESQL 元素都適當地嵌套在 esql:connection
元素內。在單個 XSP 頁面內具有多個連接元素是可能的,這樣就允許單個頁面同多個數據源交互。連接元素還必須包含定義如何創建數據庫連接的其它元素(例如,esql:pool
)。
第一種方法是簡單地引用以前定義的連接池,使用 esql:pool
元素實現這一點:
<esql:connection>
<esql:execute-query>
<esql:pool>myPoolName</esql:pool>
...
</esql:execute-query>
</esql:connection>
第二種方法是直接在 esql:connection
元素內定義連接參數。使用下列元素來實現這一點:
esql:dburl
— JDBC 連接字符串
esql:username
— 連接到數據庫的用戶名
esql:password
— 以上用戶名的密碼
esql:driver
— JDBC 驅動程序
esql:autocommit
— 指出應當自動提交 JDBC 連接
后一種方法的優點在于可以動態生成連接詳細信息 — 例如,從當前會話檢索用戶名和密碼。雖然這樣做提供了極大程度的靈活性,但是也喪失了通過使用數據庫池讓 Cocoon 管理連接的性能優點。
因此,除非需要這一動態行為,否則就建議使用 esql:pool
元素定義連接。
2.2、esql:execute-query
esql:execute-query
元素等價于 JDBC PreparedStatement
對象。它定義如何在給定數據庫連接內執行個別查詢以及應該如何處理這些查詢的結果。嵌套個別 esql:execute-query
元素以創建嵌套的數據庫查詢是可接受的。
2.3、esql:query
esql:query
元素含有將要使用這一連接執行的 SQL 查詢(SELECT、INSERT、UPDATE 或 DELETE)。對查詢結果的處理取決于執行的查詢類型。對 SELECT 語句的處理定義在 esql:results
元素內,而 INSERT、UPDATE 和 DELETE 的結果則在 esql:update-results
元素內處理。
<esql:query>
select cat_id, name from category
order by cat_id
</esql:query>
2.4、esql:row-results
使用 esql:row-results
元素來定義如何處理查詢結果中的每一行,該元素是 esql:results
的子元素。該元素的內容被轉換成由查詢生成的 JDBC ResultSet
中的每一行都執行的代碼。
<esql:results>
<esql:row-results>
<category>
<esql:get-columns/>
</category>
</esql:row-results>
</esql:results>
產生下列輸出:
<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、其它數據操作元素
esql:get-column-count
— 返回結果中列的數目。請在需要按順序處理列的地方使用該元素來建立循環。
esql:get-metadata
— 返回對 ResultSetMetadata
的引用。
esql:get-resultset
— 返回對 JDBC ResultSet
的引用以供直接操作。
esql:get-row-position
— 獲取結果中當前行的位置。請使用該元素來提供表的行數等功能。
esql:get-column-name
— 獲取當前列的名稱,必須用該列的位置來引用該列。在按順序處理結果集中的列時,請使用該元素。
esql:is-null
— 測試給定列是否具有 NULL 值。
esql:get-xml
— 添加由 JDBC ResultSet
提供的功能。檢索指定列的值并將其作為 XML 解析。在解析之前,可以有選擇地將列的值封裝在另一個元素(由 root
屬性指定)中。在原始 XML 數據存放在數據庫中時,請使用該元素。
2.7、處理空結果和錯誤
前面的這些示例假定查詢總是成功完成并且總是返回結果。顯然,事情并不總是這樣的:有些查詢可能不返回數據,也可能發生數據庫錯誤(例如,由于連接故障)。ESQL 邏輯表提供允許您處理這些情形的標記。
如果查詢不返回結果,那么可以通過使用 esql:no-rows
元素來采取行動。
...
<esql:results><results/></esql:results>
<esql:no-results><no-results/></esql:no-results>
...
esql:error-results
元素為處理 SQLException
提供了一個鉤接(hook),該異常是在處理查詢結果期間生成的。
...
<esql:error-results>
<error>
<message><esql:get-message/></message>
<trace><esql:get-stacktrace/></trace>
<string><esql:to-string/></string>
</error>
</esql:error-results>
...
將處理結果時發生的異常情形同創建數據庫連接或查詢包含語法錯誤時發生的異常情形區分開來非常重要。這些更嚴重的錯誤并不傳遞給 XSP 頁面,而是由 Cocoon 2 自身處理。
2.8、將參數傳遞給查詢
<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>
內部查詢引入了一段新 ESQL 語法:
<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
元素用于檢索外部查詢的當前類別值。新的 ancestor
元素指示從哪個外面查詢檢索該值 — 例如同第一個 esql:execute-query
ancestor 元素相關聯的結果。
2.10、分組數據
esql:group
和 esql:member
元素可以利用表連接結果中的這些模式來將相關記錄整理在一起。esql:group
元素具有 group-on
屬性。該屬性標識結果中可以用來區別外部元素(換句話就是類別)的列。元素的內容定義將對每個不同類別采用的處理,而不是定義對結果的每一行的處理。esql:member
元素定義對共享由 group-on
屬性定義的公共列的每一行的處理。這里,該元素含有建立每個專輯的 XML 結構所需的處理,最終的 XML 結構與嵌套查詢版本生成的結構相同。
<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>
三、表單驗證
3.1描述表單
下面的示例演示了用于描述表單字段、由 Form Validator Action 所支持的 XML 格式的基本語法。
<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>
說明:首先,忽略了文檔的根元素,因此它可以具有任何名稱。第二,文檔被分成了兩部分:許多字段定義后跟約束集。
每個字段定義都描述了用戶提交的參數。參數都必須有唯一的 name
屬性。字段還必須有類型,類型可以是下列之一:long
、double
或 string
。每個字段接下來可以定義許多指定為附加屬性的驗證規則:
nullable
— 標識字段是否可為空
default
— 如果沒有為字段提供值,則標識字段的缺省值
min
和 max
— 表示最小和最大值
min-len
和 max-len
— 表示最小和最大長度
matches-regex
— 定義一個必須正確匹配參數值的 POSIX 正則表達式;這允許更豐富的內容驗證,例如電子郵件地址格式
約束集描述了預定義字段的組合,對這些字段進行驗證將一遍完成,如下面所描述。約束集中的 validate
元素支持兩種附加屬性:
equals-to
— 定義參數必須匹配的固定字符串
equals-to-param
— 定義另一個應該具有相同值的參數的名稱,該參數可以完成一些功能,例如檢查用戶是否在一個驗證新密碼的表單上兩次都輸入了相同的密碼。
3.2、驗證字段
3.2.1站點地圖中對它加以聲明
同任何其它 Cocoon 2 組件一樣,在可以使用 Form Validator Action 以前,必須首先在站點地圖中對它加以聲明:
<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>
如果驗證成功,則處理 map:act
元素內的其它管道組件。就是在這里調用 insert-album.xsp
,XSP 頁面以插入已知有效的數據。
如果驗證不成功,則只執行 map:act
元素后面的組件。這樣,Actions 的行為類似于“if”語句:如果它們成功地執行了它們的處理,那么將執行嵌套在它們之內的管道組件塊;否則,就跳過該塊。
3.2.3、使用 Form Validator 邏輯表
您只可以將 Form Validator 邏輯表同 Form Validator Action 一起使用。該邏輯表通常在 XSP 頁面內使用,如果表單未能被驗證,就執行該頁面。操作將其結果的詳細分解作為 HTTP 請求參數存儲。這一邏輯表為解釋這些結果提供了一個簡單的基于標記的 API。
這一邏輯表的名稱空間是 http://apache.org/xsp/form-validator/2.0
。
下列來自邏輯表的每一元素都接受 name
屬性,該屬性表示正在測試驗證狀態的字段的名稱。
formval:is-ok
— 返回一個指示字段驗證是否成功的布爾值
formval:is-null
— 在字段本不該為空時表示該字段為空
formval:is-toosmall
— 表示字段長度比 min-len
短或值比 min
小
formval:is-toolarge
— 表示字段長度比 max-len
長或值比 max
大
formval:is-nomatch
— 表示字段未能匹配所配置的正則表達式
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 “ 中的"&"必須用它的轉義字符&
Q: Communication failure during handshake. Is there a server running on localhost:3306?
A: 嘗試下一個新版本的驅動:http://dev.mysql.com/downloads/
Class.forName("org.gjt.mm.mysql.Driver") 可以嘗試換成
Class.forName("com.mysql.jdbc.Driver")
PS: 暈菜,被這個問題搞了兩個小時。在這之前mysql和jdbc連接一直是可以用的,不過前幾天升級了一下mysql,但版本差別不大,版本號前面都有一個5。另外因為是第一次在cocoon配置,以為是配置文件搞錯了,就在那里瞎折騰。到最后,才決定要看看究竟是不是mysql的JDBC驅動版本引起的,就寫了一個簡單的JSP測試頁,結果竟然連接不成功,出現如上提示
posted on 2005-12-14 18:53
魚上游 閱讀(1767)
評論(0) 編輯 收藏 所屬分類:
爪哇世界探險