XML Server Pages(XSP) 筆記
1、基本概念
XSP可以將動態數據添加到XML 文檔中以創建更豐富的網站,也可以使 Cocoon 2 集成現有數據源和/或 API 以在因特網上用多種格式發布數據。它是一種能夠創建動態 XML 數據源以便將數據傳輸到 Cocoon 2 管道的 Cocoon 2 技術。通過使用 XML 標記和應用邏輯的組合來描述這些數據源,然后由 Cocoon 2 引擎自動將這種組合編譯為 Java 類。XSP 為使用 Cocoon 2 開發應用程序提供了一個靈活的平臺。例如,Cocoon 2 應用程序可以顯示現有應用程序數據庫中的信息,而且啟用了更為多樣的數據發送選項。通過提供一種通過 XML 界面顯示數據源的方法,XSP 允許在諸如中間件和文檔發布那樣的應用程序集成環境中使用 Cocoon 2。
1.1 XSP 與 JSP
1.1.1相同點:
1)由程序代碼和標記的混合體組成
2)被編譯成用于執行的二進制形式
3)允許創建定制標記庫
1.1.2不同點:
1) XSP 為將任何編程語言中的代碼與 XML 標記混合在一起提供了一個框架。
2) XSP 生成動態數據
XSP 生成動態數據,而不是動態表示。與之不同,JSP 則是一種通常用于在一系列處理步驟的最后階段產生 HTML 或 XML 的表示層技術。XSP 頁面為 Cocoon 管道生成 XML 數據,而由管道創建了所期望的表示。
1.2 XSP 編譯過程
- 解析 XSP 文檔
- 通過使用專用 XSLT 樣式表轉換 XSP 頁面,以生成 Java 源代碼
- 通過使用代碼格式化器,在整齊地縮排和格式化源代碼后,存儲結果 Java 文件
- 將源代碼編譯成生成器
- 在請求管道中裝入并執行已編譯的生成器
1.3 一個XSP運行例子
Cocoon 2 提供了一個協調個別 XSP 頁面的編譯和執行的 ServerPagesGenerator
組件。在網站地圖中,ServerPagesGenerator
聲明如下:
<map:generators default="file">
<map:generator name="xsp" src="org.apache.cocoon.generation.ServerPagesGenerator"/>
<!-- ... other generator declarations ... -->
</map:generators>
要在管道中使用這個生成器,只須簡單聲明應當使用(而不是缺省值)并且指出在何處可以找到特定的 XSP 頁面的源代碼,如下所示:
<map:pipeline>
<map:match pattern="tutorial/*.xml">
<map:generate type="xsp" src="tutorial/{1}.xsp"/>
<map:serialize type="xml"/>
</map:match>
</map:pipeline>
2、語法
2.1 xsp:page 元素
xsp:page
元素是每個 XSP 文檔的根元素。
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp">
<!-- page contents -->
</xsp:page>
2.2 xsp:structure 和 xsp:include 元素
當添加利用標準或定制 Java API 的編程邏輯時,必須在 XSP 中指出生成的源代碼中需要另外的 import 語句以確保編譯成功地完成。xsp:structure
和 xsp:include
元素用于向代碼生成過程提供這些附加提示。
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp">
<xsp:structure>
<xsp:include>java.util.Calendar</xsp:include>
<xsp:include>java.text.*</xsp:include>
</xsp:structure>
<!-- page contents -->
</xsp:page>
2.3 xsp:logic 元素
xsp:logic
元素用于將 Java 代碼塊添加到 XSP。例如:
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp">
<xsp:logic>
public String getTime()
{
return java.util.Calendar.getInstance().getTime().toString();
}
</xsp:logic>
<document/>
</xsp:page>
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp">
<document>
<xsp:logic>
SimpleDateFormat format = new SimpleDateFormat("EEE, MMM d, yyyy");
String timestamp = format.format(
java.util.Calendar.getInstance().getTime()
);
</xsp:logic>
<time><xsp:expr>timestamp</xsp:expr></time>
<!-- additional elements -->
</document>
</xsp:page>
這個代碼包含了對 XSP 文檔求值時創建時間戳記的邏輯。然后通過使用 xsp:expr
,這個時間戳記被添加到了 time
元素內的文檔中。
2.4 避免錯誤,保持良好的格式
2.4.1
程序代碼與 XML 標記
把 if (a < b && c > d) { ... }改為①if (a < b && c >) { ... }或者②
<xsp:logic>
<![CDATA[
if (a < b && c > d) { ... }
]]>
</xsp:logic>
但是②
將忽略這些節內出現的任何 XSP 或用戶元素,而將它們當作純文本而不是 XML 標記進行處理,這樣更可能導致隱蔽的、耗時的錯誤。
2.4.2
xsp:logic
元素內 XML格式規則
以下有錯:
<search-results>
<xsp:logic>
if (firstResult())
{
<result id="first">
} else
{
<result>
}
<!-- ...result generation code here... -->
</result>
</xsp:logic>
</search-results>
應改為
<search-results>
<xsp:logic>
if (firstResult())
{
<result id="first">
<!--... handle first result..-->
</result>
} else
{
<result>
<!--...handle other results...-->
</result>
}
</xsp:logic>
</search-results>
2.5 xsp:expr 元素
xsp:expr
元素等價于在 JSP 中實現類似角色的 <%= ... %>
表達式語法。
<elements>
<xsp:logic>
for (int i=1; i<11; i++)
{
<element><xsp:expr>i</xsp:expr></element>
}
</xsp:logic>
</elements>
2.6 通過使用 xsp:element 生成動態元素
通過使用 xsp:element
,還可以動態地創建元素,它的工作原理類似于其 XSLT 等價機制的工作原理。
<xsp:element>
<xsp:param name="name"><xsp:expr>"myElementName"</xsp:expr></xsp:param>
Element content
</xsp:element>
還可以與一個特定的名稱空間和前綴關聯
<xsp:element prefix="my" uri="http://www.examples.org">
<xsp:param name="name"><xsp:expr>"myElementName"</xsp:expr></xsp:param>
Element content
</xsp:element>
這個示例生成了以下 XML 輸出:
<my:myElementName xmlns:my="http://www.examples.org">Element content</my:myElementName>
還可能動態地生成名稱空間 URI 和前綴。無須添加 prefix
和 uri
屬性,而是使用帶適當名稱的附加 xsp:param
元素。下列代碼等價于上面的示例:
<xsp:element prefix="my" uri="http://www.examples.org">
<xsp:param name="name"><xsp:expr>"myElementName"</xsp:expr></xsp:param>
<xsp:param name="prefix">"my"</xsp:param>
<xsp:param name="uri">"http://www.examples.org"</xsp:param>
Element content
</xsp:element>
2.7 通過使用 xsp:attribute 生成動態屬性
xsp:attribute
元素的工作原理類似于 xsp:element
,它允許動態創建屬性的名稱及其值:
<xsp:element>
<xsp:param name="name"><xsp:expr>"myElementName"</xsp:expr></xsp:param>
<xsp:attribute name="myAttribute">myAttributeValue</xsp:attribute>
Element content
</xsp:element>
這個屬性的名稱定義在 name
屬性內,盡管是用與 xsp:element
類似的方法定義的,但它還能通過使用 xsp:param
子元素來定義。屬性值被指定成元素內容。這可以是一個簡單文本值或更有效地由 xsp:expr
元素生成。
2.8 創建注釋和處理指令
2.8.1 創建注釋:
<xsp:comment>This is a comment</xsp:comment>
然后這個注釋變成:
<!-- This is a comment -->
2.8.2 創建處理指令類似于創建動態元素或屬性:
<xsp:pi target="myApplication">
<xsp:expr>"param1=value, param2=value, generatorTimestamp=" +
System.currentTimeMillis()</xsp:expr>
</xsp:pi>
輸出如下:
<?myApplication param1=value, param2=value, generatorTimestamp=1017407796870?>
還可以通過在 xsp:param
元素內創建處理指令的目標來自動生成它,如同以下示例演示的那樣:
<xsp:pi>
<xsp:param name="target"><xsp:expr>"myApplication"</xsp:expr></xsp:param>
<xsp:expr>"param1=value, param2=value, generatorTimestamp=" +
System.currentTimeMillis()</xsp:expr>
</xsp:pi>
3 邏輯單
邏輯單是能被鉤接入代碼生成過程以允許創建定制標記庫的 XSLT 轉換。這些邏輯單使 XSP 頁面更容易處理,從而減少了直接嵌入代碼的需要。
3.1 使用邏輯單
每個邏輯單都與一個特殊的名稱空間關聯。使用邏輯單僅僅涉及在 XSP 文檔中聲明相應的名稱空間,然后在需要的時候添加來自那個名稱空間的元素。
<xsp:page language="java"
xmlns:xsp="http://apache.org/xsp"
xmlns:util="http://apache.org/xsp/util/2.0">
<clock>
<day><util:time format="EE"/></day>
<month><util:time format="MMMM"/></month>
<year><util:time format="yyyy"/></year>
<time><util:time format="HH:mm:ss 'on' dd/MM/yyyy"/></time>
</clock>
</xsp:page>
3.2內置邏輯單
3.2.1 環境邏輯單
在這個環境類別中有四個邏輯單,每個邏輯單都提供對與 Web 請求關聯的處理環境的特殊方面的訪問。這些邏輯單提供的功能類似于與 JSP 頁面關聯的隱式對象(例如,request
和 response
對象)提供的功能,并且是從 HTTP Servlet API 中直接提取的。
1) 請求(request)邏輯單
提供了對請求屬性的訪問,包括對請求參數、請求方法(例如,GET
、POST
等等)以及請求標題的訪問。當請求參數的某些方面用于改變輸出文檔的生成時,這個邏輯單就格外有用。
2)響應(response)邏輯單
提供對與當前請求關聯的 HTTP 響應的限制訪問;它只提供對請求標題的訪問。XSP 文檔不能用與 Java Servlet 或 JSP 頁面相同的方法執行包含或轉發,因為分離問題是 Cocoon 2 體系結構的核心部分。這個功能描述在網站地圖中;XSP 頁面生成 XML 內容而不指導處理。
3)會話(session)邏輯單
提供了對 HTTP 會話信息的訪問,包括創建和刪除會話以及添加和除去會話屬性的能力。很明顯,這個功能在必須為上下文維護用戶會話的 Web 應用程序中是最有用的。Cocoon 2 中的會話管理正好等價于它的 JSP 對手。
4)cookie 邏輯單
提供了 cookie 維護功能,諸如添加和除去 cookie、允許優先存儲到用戶的瀏覽器中。
3.2.2 實用程序邏輯單
1) 日志(log)邏輯單
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp"
xmlns:util="http://apache.org/xsp/log
/2.0">
<log:debug>This is a debug message from an XSP generator</log:debug>
</xsp:page>
2)
發送郵件(sendmail) 邏輯單
<sendmail:send-mail from="myemail@email.com" to="user@user.com" smtphost="smtphost@email.com">
<xsp:param name="subject"><xsp:expr>"The subject of this email..."</xsp:expr></xsp:param>
<xsp:param name="body"><xsp:expr>"The body of this email..."</xsp:expr></xsp:param>
</sendmail:send-mail>
3) 時間邏輯單
如前面的示例。
3.2.3 數據操作
1) 表單驗證器(form validator)邏輯單
表單驗證器(form validator)邏輯單從未真正單獨使用。它向 Cocoon 表單驗證器行為(Cocoon Form Validator Action)提供一個整齊的界面。這個行為能夠對從 HTML 表單發送到 Cocoon 應用程序的數據執行基本驗證操作,包括檢查整數的最小和最大值、檢查字符串的大小以及檢查提供的某些參數。一個著名功能是能夠測試傳遞的變量是否匹配給定的正則表達式。
2) esql 邏輯單
esql 邏輯單提供了執行這一步的方法,并提供了更多的功能,包括選擇、刪除和更新數據庫。本質上,esql 邏輯單提供了將 SQL 語句直接嵌入到 XSP 文檔的方法。然后這個邏輯單生成相應的 JDBC 代碼來實現 SQL 操作,這樣通過使用 Cocoon 2 簡化了對數據庫數據的操作和檢索。
3.3 編寫邏輯單
因為邏輯單轉換可能以任何順序發生,所以每個邏輯單都需要保留輸入文檔中它不理解的任何內容。換句話說,邏輯單的基本模板是恒等轉換。這是一個將它的輸入未做更改而直接簡單復制到它的輸出的轉換。
<xsl:template match="time:time">
<xsp:logic>
SimpleDateFormat timeFormat = new SimpleDateFormat("<xsl:value-of select="@format"/>");
</xsp:logic>
<xsp:expr>
timeFormat.format(java.util.Calendar.getInstance().getTime())
</xsp:expr>
</xsl:template>
該單一模板與 time
元素匹配,并用封裝在 xsp:logic
和 xsp:expr
元素中的代碼來替代它們以創建日期。所需的日期格式由用戶通過這個元素上的 format
屬性來說明。
3.4 配置邏輯單
在該配置文件中搜索 xsp-language
元素,并注意它包含一個名為 target-language
的子元素。應聲明這個元素內的所有邏輯單。還可能看到已預先定義了內置邏輯單。這里是 util 邏輯單的項:
<builtin-logicsheet>
<parameter name="prefix" value="util"/>
<parameter name="uri" value="http://apache.org/xsp/util/2.0"/>
<parameter name="href" value="resource://org/apache/cocoon/components/language/markup/xsp/java/util.xsl"/>
</builtin-logicsheet>
另例如:
<!--*************** Test By David *************** -->
<builtin-logicsheet>
<parameter name="prefix" value="xsp-time"/>
<parameter name="uri" value="$CATALINA_HOME/webapps/cocoon/WEB-INF/classes/logicsheets/time.xsl"/>
<parameter name="href" value="resource://logicsheets/time.xsl"/>
</builtin-logicsheet>
3.5 邏輯單的開發技巧
3.5.1 使用助手類:
雖然創建邏輯單將從 XSP 頁面中提取出程序代碼,但這個代碼仍被鎖藏在 XSLT 樣式表中。這使不依賴 Cocoon 而要維護和測試代碼很困難。一個好的設計技巧是將盡可能多的代碼放入助手類中。這樣使得邏輯單的實現簡化為只是收集參數,然后調用所需的助手方法。內置邏輯單遵循這個指南,并且每個邏輯單都有單個助手類。
3.5.2 創建邏輯單“宏”:
宏是記錄和重新執行一系列操作的一個簡單快速的方法。在特殊應用程序中的 XSP 頁面可能要重復創建相同的 XML 結構或用同樣的方法調用其它邏輯單。提取出 XSP 頁面中的公共塊,以創建描述這個重復結構的較高級別元素(例如,宏)是很有用的。因為 Cocoon 2 遞歸地應用邏輯單,直到處理完所有名稱空間為止,一個邏輯單的實現可以添加另一個邏輯單上的元素。這種組合可以大大降低 XSP 頁面的復雜程度。
3.5.3 考慮用戶:
當考慮在邏輯單中提供什么樣的標記時,請考慮最終用戶。他們需要怎樣的靈活性?例如,可以將什么樣的參數發送給標記?只能通過屬性或嵌套的 xsp:param
元素發送參數嗎?后者更加靈活,因為它允許用戶通過使用 xsp:expr
動態地創建參數值,而 xsp:expr
不能在屬性內使用。還要考慮如何命名標記。賦予它一個清晰和好記的名稱,這樣它所做的就顯而易見了。并不是每個人都樂意深入研究邏輯單的實現來感受這一點的。這個建議的一個很明顯擴展是向邏輯單提供支持文檔;這使用戶能快速找到標記的含義以及如何使用它。
posted on 2005-12-08 20:08
魚上游 閱讀(1208)
評論(0) 編輯 收藏 所屬分類:
爪哇世界探險