<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    簡介

    Jakarta Tapestry是一個(gè)開源的Java Web應(yīng)用框架。你或許會說:"大同小異的東西罷了."多數(shù)

    情況下,我同意你的觀點(diǎn),然而,只要花上些許時(shí)間研究一下,你會發(fā)現(xiàn)Tapestry跟別的框架大為不同,它是值得嚴(yán)肅對待的。

    Tapestry是一個(gè)基于控件的框架以致于用它開發(fā)Web應(yīng)用類似開發(fā)傳統(tǒng)的GUI應(yīng)用。你用Tapestry開發(fā)Web應(yīng)用時(shí)你無需關(guān)注以操作為中心的(operation-centric) Servlet API.引用Tapestry網(wǎng)站上的一句話:"Tapestry用對象(objects),方法(methods),屬性(properties)替代以往的URLs和查詢參數(shù), 重新詮釋W(xué)eb應(yīng)用開發(fā).Tapestry 3.0即將發(fā)布,它有大量的改進(jìn)和新的特性。

    Tapestry的目標(biāo)

    簡單性

    Tapestry應(yīng)用與傳統(tǒng)的Servlet應(yīng)用相比代碼量更少。大多數(shù)傳統(tǒng)的Servlet應(yīng)用包含如下厭煩和

    重復(fù)的任務(wù):解析查詢參數(shù),處理HttpSession對象,構(gòu)建URLs。Tapestry消除了傳統(tǒng)Servelt應(yīng)用中許多無趣的"銜接"代碼("plumbing" code)使開發(fā)者把精力集中到應(yīng)用邏輯上來。

    一致性

    Tapestry為開發(fā)Web應(yīng)用的頁面提供了一致的方式。這樣有助于消除傳統(tǒng)Servlet應(yīng)用開發(fā)中臆測。由于所有Tapestry應(yīng)用中的頁面都是用相同的可復(fù)用的控件組織而成,所以工作方式是相似的。

    效率

    Tapestr應(yīng)用擁有高度的可升級性,它利用緩存和對象池使每個(gè)請求的處理時(shí)間最小化。Tapestry應(yīng)用擁有跟傳統(tǒng)Servlet應(yīng)用相仿的性能。

    錯(cuò)誤反饋

    任何開發(fā)過Servlet/JSP應(yīng)用的人毫無質(zhì)疑有類似經(jīng)歷:為了找出Web.xml文件有什么錯(cuò)誤,不得不花費(fèi)大量時(shí)間察看瀏覽器中的堆棧信息。Tapestry擁有優(yōu)秀的錯(cuò)誤報(bào)告方式,最值得一提的是它會指出哪個(gè)文件以及那一行導(dǎo)致了錯(cuò)誤。

    與Struts比較

    既然Apache Struts可能是當(dāng)今應(yīng)用最廣泛的Web應(yīng)用框架,拿Tapestry與它比較是唯一公平的。以下是一些觀察比較,它們來源于為這篇文章開發(fā)的幾個(gè)簡單的Tapestry應(yīng)用和為幾個(gè)Struts工程的工作經(jīng)歷。

    Struts的優(yōu)點(diǎn)

    1 一個(gè)Servlet/JSP開發(fā)者熟悉Struts無需太久。然而Tapestry的學(xué)習(xí)曲線會長一點(diǎn),因?yàn)樗c流行的Web應(yīng)用框架不太相同 。

    2 Struts在Java社區(qū)里被廣泛接受和使用。為你的項(xiàng)目找一個(gè)好的Struts開發(fā)人員并非難事,Tapestry近來在開發(fā)者社區(qū)里 贏得一些關(guān)注,然而仍有許多Java老手不知道Tapestry為何物。

    3 既然Struts被如此廣泛的使用,所以有很多Struts資源可供參考。相比大多數(shù)開源軟件,Tapestry擁有非常可觀的資源和文檔,但跟Struts相比仍有差距。

    Tapestry的優(yōu)點(diǎn)

    1 你開發(fā)一個(gè)Tapestry應(yīng)用無需關(guān)注Servlet API,你也無須為你的Servlet應(yīng)用寫一些典型的"銜接"代碼。雖然Struts簡化了工作,然而Servlet API 仍是你需面對的。

    2 Tapestry的頁面模板除了幾個(gè)特別屬性和標(biāo)識就是一個(gè)標(biāo)準(zhǔn)的HTML文件。 如果你是一個(gè)開發(fā)小組中的HTML設(shè)計(jì)高手,然而你不懂Java或JSP,這就給你帶來很大方便。

    3 因?yàn)門apestry頁面是標(biāo)準(zhǔn)的HTML,所以可以用HTML所見即所得(WYSIWYG)編輯器編輯和預(yù)覽該頁。當(dāng)一個(gè)頁需要修改它的外觀并不需要通知服務(wù)器讓它重新編譯JSP.

    4 Tapestry不需要一個(gè)至高的,整個(gè)應(yīng)用范圍的配置文件。Tapestry應(yīng)用中的每一頁是獨(dú)立的,改變一頁不會影響開發(fā)其他 頁面的開發(fā)者,因?yàn)椴]有一個(gè)配置文件把所有頁面的瀏覽粘連在一起。

    5 Tapestry擁有極好的錯(cuò)誤報(bào)告。如果你在一個(gè)頁的模板或頁面規(guī)范犯了一個(gè)錯(cuò)誤,Tapestry會指出導(dǎo)致錯(cuò)誤的行號。

    6 用Tapestry開發(fā)是種樂趣。這樣說聽上去似乎老調(diào),然而用Tapestry開發(fā)一個(gè)Web應(yīng)用相比應(yīng)用其他流行的框架更為自然有趣。用Tapestry開發(fā)是應(yīng)用了一種基于控件的架構(gòu),與開發(fā)傳統(tǒng)的GUI應(yīng)用非常相似。

    Tapestry 架構(gòu)

    Tapestry框架是標(biāo)準(zhǔn)Servlet API的一種擴(kuò)展。它需要J2SDK1.2或更高版本的J2SDK和一個(gè)與Servlet API 2.2(或更高)兼容的應(yīng)用服務(wù)器/Servlet容器。

    一個(gè)Tapestry應(yīng)用由許多擁有唯一名稱的頁面組成。一個(gè)頁面由一個(gè)模板和一些可復(fù)用的控件構(gòu)成。模板由標(biāo)準(zhǔn)的HTML標(biāo)簽和一些額外的屬性和標(biāo)簽構(gòu)成,這些額外的屬性和標(biāo)簽是為了告訴Tapestry框架這個(gè)頁面的那些部分是由Tapestry控件組成。

    簡單的Tapestry應(yīng)用

    為了最好的描述構(gòu)建一個(gè)Tapestry頁面的方方面面,我們可以看看這個(gè)Pig Latin翻譯器應(yīng)用的代碼。這個(gè)應(yīng)用只有一個(gè)頁面,在這頁里輸入一個(gè)text值把它翻譯成Pig Latin,然后把翻譯好的值顯示給用戶。

    在Tapestry應(yīng)用中每個(gè)頁由3個(gè)部分組成:一個(gè)HTML模板,一個(gè)頁面規(guī)范文件,一個(gè)Java類。

    這里有這個(gè)頁面屏幕抓圖:

    /Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226281.jpg


    頁面模板由標(biāo)準(zhǔn)的HTML標(biāo)簽和一些額外的屬性和標(biāo)簽構(gòu)成,這些額外的屬性和標(biāo)簽是為了告訴Tapestry框架這個(gè)頁面的那些部分是由Tapestry控件組成。頁面模板存放在Web應(yīng)用的根context目錄下。通常,Tapestry在啟動時(shí)會尋找和呈現(xiàn)一個(gè)名叫"Home"的頁。雖然我們可以改變這種行為,但依照Tapestry的慣例會更簡單。

    Home.html
    ??? <html>
    ??? <head>
    ????? <title>Tapestry Pig Latin Translator</title>
    ??? </head>
    ??? <body>
    ????? <h1>Pig Latin Translator</h1>
    ????? <form jwcid="@Form"① listener="ognl:listeners.submit"②>
    ????? <table border="1">
    ??????? <tr>
    ????????? <td>Value to Translate:</td>
    ????????? <td>
    ??????????? <input type="text" jwcid="@TextField"③ value="ognl:inputValue"/>
    ????????? </td>
    ??????? </tr>
    ??????? <tr>
    ????????? <td>Pig Latin:</td>
    ????????? <td>
    ??????????? <jwcid="@Insert"④ value="ognl:pigLatinValue"/>
    ????????? </td>
    ??????? </tr>
    ????? </table>
    ????? <input type="submit" jwcid="@Submit"⑤ value="Translate"/>
    ????? </form>
    ??? </body>
    ??? </html>
    ???

    頁面模板的絕大部分是普通的HTML,只有少部分Tapestry特有的屬性和標(biāo)簽。這種模板機(jī)制的優(yōu)勢就是Tapestry頁面模板可以在一個(gè)可見即所得的編輯器里創(chuàng)建和預(yù)覽。描述Tapestry控件部分的標(biāo)識是有限的和突出的。

    標(biāo)識里的jwcid所指是被應(yīng)用的Tapestry控件的Java Web Component ID.在上面代碼斷里,我們是隱式地使用控件。隱式的控件是指直接在頁面模板里聲明使用的控件,。jwcid的前綴 '@ '符號就是通知Tapestry這里聲明使用了一個(gè)隱式控件。

    在上面的Pig Latin Translator頁面模板里用了四個(gè)控件:Form①, TextField③, Insert④ 和Submit⑤。它們只是Tapestry框架提供的包含超過40個(gè)控件的控件庫里的四個(gè)。在后面的范例中,我們將會看到如何使用顯式控件。顯式控件是指控件在頁面規(guī)范文件里聲明后再使用的控件。

    在前面的HTML模板里,使用控件的同時(shí),也為控件指定了參數(shù)。例如控件Form①有一個(gè)listener②參數(shù)它指定了當(dāng)表單提交時(shí)對應(yīng)的頁面類調(diào)用的方法名稱。那個(gè)ognl:前綴的使用貫穿頁面的HTML模板,指向的是Object Graph Navigation Language (OGNL)。OGNL是一個(gè)強(qiáng)大的開源的表達(dá)式語言,用于將頁面內(nèi)控件的屬性綁定到頁面類的屬性。

    現(xiàn)在我們看看頁面規(guī)范文件。頁面規(guī)范文件是一個(gè)擴(kuò)展名為page的XML文件,這個(gè)文件有許多職責(zé),在眾多職責(zé)中最基本是指定頁面對應(yīng)的Java類。頁面規(guī)范文件存放在webapp的WEB_INF目錄。

    Home.page
    ??? <?xml version="1.0"?>
    ??? <!DOCTYPE page-specification PUBLIC
    ??????? "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
    ??????? "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd>
    ??? <page-specification class="Home">
    ??????? <property-specification name="inputValue" type="java.lang.String"/>
    ??????? <property-specification name="pigLatinValue" type="java.lang.String"/>
    ??? </page-specification>

    ???
    頁面規(guī)范文件的根元素有一個(gè)class的屬性,它指定了這個(gè)頁對應(yīng)的Java類。這個(gè)類必須要實(shí)現(xiàn)org.apache.tapestry.Ipage接口。頁面規(guī)范同時(shí)頁定義了兩個(gè)屬性(property)元素,以便Tapestry在頁面類里創(chuàng)建新的屬性。

    Tapestry框架提供了org.apache.tapestry.html.BasePage class,它實(shí)現(xiàn)了Ipage接口。頁面類被存放在Web-INF/classes目錄下,跟你的Web應(yīng)用的所需要的其他類放在一起。

    Home.java
    ??? import org.apache.tapestry.html.BasePage;
    ??? import org.apache.tapestry.IRequestCycle;

    ??? public abstract class Home extends BasePage {
    ??????? public abstract String getInputValue();
    ??????? public abstract void setInputValue(String inputValue);

    ??????? public abstract String getPigLatinValue();
    ??????? public abstract void setPigLatinValue(String pigLatinValue);

    ??????? public void submit(IRequestCycle cycle) {
    ??????????? String inputValue = getInputValue();
    ??????????? String pigLatinValue = new PigLatinTranslator().translate(inputValue);
    ??????????? setPigLatinValue(pigLatinValue);
    ??????? }
    ??? }
    ???

    你要提醒的第一件事或許是這個(gè)類為什么是抽象類。它還有幾個(gè)抽象方法訪問inputValue,pigLatinValue屬性。這里利用了Tapestry會在運(yùn)行時(shí)刻創(chuàng)建子類的功能,這個(gè)子類會創(chuàng)建你在頁面規(guī)范里聲明的屬性和生成相應(yīng)的訪問方法。

    在表單提交時(shí)頁面類的submit方法會被調(diào)用。為什么會這樣?因?yàn)槲覀冊陧撁婺0謇飳orm控件的listener屬性指定為:ognl:listeners.submit。這就意味著一個(gè)名叫submit的listener會通過頁面類的listeners被訪問。

    所有的頁面類和控件類都從org.apache.tapestry.AbstractComponent這個(gè)類繼承來一個(gè)叫l(wèi)isteners的屬性。當(dāng)submit方法完成后,頁面會顯示被翻譯好的詞。

    最后講講Web.xml這個(gè)Web發(fā)布描述文件。Tapestry,像許多其他的流行的Web應(yīng)用框架一樣,由一個(gè)Servlet構(gòu)成,但是還需要一個(gè)發(fā)布描述文件。那個(gè)發(fā)布描述文件應(yīng)該被存放在WEB-INF目錄。

    web.xml
    ??? <?xml version="1.0"?>
    ??? <!DOCTYPE web-app PUBLIC
    ??????? "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    ??????? "http://java.sun.com/dtd/web-app_2_3.dtd>
    ??? <web-app>
    ??????? <display-name>Tapestry Pig Latin Translator</display-name>

    ??????? <servlet>
    ??????????? <servlet-name>tapestry</servlet-name>
    ??????????? <servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
    ??????????? <load-on-startup>1</load-on-startup>
    ??????? </servlet>

    ??????? <servlet-mapping>
    ??????????? <servlet-name>tapestry</servlet-name>
    ??????????? <url-pattern>/app</url-pattern>
    ??????? </servlet-mapping>
    ??? </web-app>
    ???

    雖然Pig Latin翻譯應(yīng)用非常簡單,但是它會讓你對在Tapestry應(yīng)用中一個(gè)頁面的3個(gè)組成部分有了基本的了解。它也展示了創(chuàng)建一個(gè)Tapestry應(yīng)用的一個(gè)頁面只需寫多么少的代碼。

    表單輸入驗(yàn)證

    Tapestry 提供了一些控件以便校驗(yàn)用戶的輸入。校驗(yàn)子系統(tǒng)是ValidField控件的核心。在下面的登錄應(yīng)用中我們將使用ValidField控件。ValidField控件位于表單內(nèi),對用戶在客戶端的校驗(yàn)提供了有用的反饋和視覺上的錯(cuò)誤提示。

    區(qū)域化

    在Tapestry中,區(qū)域化是相當(dāng)簡單的。Tapestry允許文字和圖形的區(qū)域化。為了區(qū)域化頁面的內(nèi)容,你可以為每一個(gè)添加一個(gè)properties文件,或者提供一個(gè)區(qū)域化的模板。為每個(gè)頁面提供一個(gè)資源文件的方式遠(yuǎn)比管理和維護(hù)一個(gè)巨大的全局的應(yīng)用范圍的資源文件簡單。如果頁面的區(qū)域化并不僅僅只是文字信息的區(qū)域化,例如頁面的布局不同或者組成的控件不同,這樣情況提供區(qū)域化的頁面模板就能派上用場了。我們會在下面的登錄應(yīng)用的使用Tapestry區(qū)域化。

    創(chuàng)建控件

    Tapestry發(fā)布時(shí)提供了40多個(gè)自帶的控件。如果你想知道更多的關(guān)于Tapestry自帶控件的信息,請參考Tapestry Component Reference.想看看Tapestry的控件的應(yīng)用范例可訪問Tapestry Component Workbench.如果你發(fā)現(xiàn)你需要一個(gè)Tapestry本身沒提供的控件,你可以自己創(chuàng)建一個(gè)。創(chuàng)建你自己的Tapestry控件跟創(chuàng)建一個(gè)頁面是相似的。一個(gè)典型的Tapestry控件由一個(gè)控件規(guī)范文件(XML文檔),一個(gè)HTML控件模板,一個(gè)實(shí)現(xiàn)了org.apache.tapestry.Icomponent接口的Java類。這個(gè)議題有點(diǎn)超出本文的范圍,但是如果你有興趣學(xué)習(xí)如何創(chuàng)建你自己的Tapestry控件,你可以參考Tapestry的原創(chuàng)人,Tapestry In Action 一書的作者--Howard Lewis Ship寫的 Designing Tapestry Mega-Components

    Tapestry 登錄應(yīng)用

    你在Pig latin翻譯器應(yīng)用中看到了Tapestry的一些基本特性。與其用一個(gè)復(fù)雜的應(yīng)用展示Tapestry所有的特性以致于壓得你揣不過氣來,還不如通過一些簡單的應(yīng)用讓你找到一點(diǎn)對Tapestry的感覺。下面這個(gè)應(yīng)用展示Tapestry如何處理頁面導(dǎo)航,區(qū)域化,驗(yàn)證和其他一些特性。

    這里有一個(gè)Home頁的屏幕抓圖,下面跟著它的頁面模板。

    /Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226283.jpg

    Home.html
    ??? <html>
    ??? <head>
    ??????? <title>Welcome to the Tapestry Login Application</title>
    ??? </head>

    ??? <body>
    ??????? <h1>Welcome to the Tapestry Login Application</h1>
    ??????? <span jwcid="@PageLink"① page="Login">Login</span>
    ??? </body>
    ??? </html>
    ???
    這個(gè)Home頁的頁面模板除了一個(gè)jwcid屬性定義使用一個(gè)Tapestry PageLink①控件以外都是標(biāo)準(zhǔn)的HTML。

    PageLink控件生成了一個(gè)指向Login頁的超鏈接。既然Home頁沒有任何動態(tài)的行為所以它不需要頁面規(guī)范和頁面對應(yīng)的Java類。

    這里是Login頁的屏幕抓圖,后面跟著是它的頁面模板。

    /Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226285.jpg

    Login.html
    ??? <html>
    ??? <head>
    ??????? <title>
    ??????????? <span key="title">①Login</span>
    ??????? </title>
    ??? </head>

    ??? <body jwcid="@Body">②
    ??????? <span jwcid="@Conditional" condition="ognl:beans.delegate.hasErrors">③
    ??????????? <div style="color: red">
    ??????????????? <span jwcid="@Delegator" delegate="ognl:beans.delegate.firstError">④
    ??????????????????? Error Message
    ??????????????? </span>
    ??????????? </div>
    ??????? </span>
    ??????? <p style="font-weight: bold" >
    ??????????? <span key="hint">Hint: Your password is your username spelled backwards.</span>
    ??????? </p>
    ???????
    ??????? <form jwcid="@Form" listener="ognl:listeners.login" delegate="ognl:beans.delegate">


    ??????????? <table>
    ??????????????? <tr>
    ??????????????????? <td align="right">
    ??????????????????????? <span jwcid="@FieldLabel" field="ognl:components.inputUsername"⑥>
    ??????????????????????????? Username:
    ??????????????????????? </span>
    ??????????????????? </td>
    ??????????????????? <td>
    ??????????????????????? <input type="text" jwcid="inputUsername"⑦ value="simpson_h"

    size="30"/>
    ??????????????????? </td>
    ??????????????? </tr>

    ??????????????? <tr>
    ??????????????????? <td align="right">
    ??????????????????????? <span jwcid="@FieldLabel" field="ognl:components.inputPassword">
    ??????????????????????????? Password:
    ??????????????????????? </span>
    ??????????????????? </td>
    ??????????????????? <td>
    ??????????????????????? <input type="text" jwcid="inputPassword" hidden="true" value=""

    size="30"/>
    ??????????????????? </td>
    ??????????????? </tr>

    ??????????????? <tr>
    ??????????????????? <td colspan="2" align="center">
    ??????????????????????? <input type="submit" jwcid="@Submit" value="message:login"/>
    ??????????????????? </td>
    ??????????????? </tr>
    ??????????? </table>
    ??????? </form>
    ??? </body>
    ??? </html>
    ???

    這個(gè)頁面模板大多數(shù)是通常的HTML。我們從頁面模板中可以看到Tapestry的區(qū)域化特性:它使用一個(gè)span元素,這個(gè)span元素帶有一個(gè)叫key的屬性,key的值映射到Login.properties文件里一個(gè)屬性。一個(gè)Body控件被聲明使用,因?yàn)樗鼘蛻舳说腏avaScript校驗(yàn)是必需的。

    為Form component⑤設(shè)定delegate屬性激活表單輸入驗(yàn)證。delegate屬性是我們在頁面規(guī)范里聲明的org.apache.tapestry.valid.IvalidationDelegate的實(shí)現(xiàn)類。如果驗(yàn)證錯(cuò)誤發(fā)生了,我們用Conditional component③控件判斷delegate是否有任何錯(cuò)誤,如果有就把第一個(gè)錯(cuò)誤④顯示給用戶。如果ognl 表達(dá)式ognl:beans.delegate.hasErrors 為true,Conditional控件將顯示它的內(nèi)容實(shí)體。所有的頁面類和控件類都從AbstractComponent繼承來一個(gè)叫beans的屬性。這個(gè)beans屬性是一個(gè)org.apache.tapestry.IbeanProvider的實(shí)例,利用它可以通過名字取得在頁面規(guī)范文件里定義的beans.FieldLabel⑥被用于為inputuserName validField控件顯示標(biāo)簽,這個(gè)FieldLabel控件也被用來與表單的驗(yàn)證代理協(xié)作,指出包含錯(cuò)誤的輸入域。
    InputUserName⑦控件是一個(gè)顯示控件的例子。顯式控件是指在頁面規(guī)范文件聲明的控件。InputUsername和inputPassword控件都是顯式的,它們與FieldLabel聯(lián)合顯示它們的displayName屬性。

    下面的是Login頁的資源文件。Login.properties跟頁面規(guī)范一并存放在WEB-INF目錄。

    Login.properties
    ??? title = Login to the Application
    ??? hint = Hint: Your password is your username spelled backwards.
    ??? login = Login
    ??? username = Username:
    ??? password = Password:
    ??? invalidpassword = Invalid Password
    ???
    Here is the page specification for the Login page.
    Login.page
    ??? <?xml version="1.0"?>
    ??? <!DOCTYPE page-specification PUBLIC
    ??????? "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
    ??????? "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd>

    ??? <page-specification class="com.ociweb.tapestry.Login">
    ??????? <bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/>①

    ??????? <bean name="requiredValidator"②
    ??????????? class="org.apache.tapestry.valid.StringValidator">
    ??????????? <set-property name="required" expression="true"/>
    ??????????? <set-property name="clientScriptingEnabled" expression="true"/>
    ??????? </bean>

    ??????? <property-specification name="username" type="java.lang.String"/>
    ??????? <property-specification name="password" type="java.lang.String"/>

    ??????? <component id="inputUsername" type="ValidField"> ③
    ??????????? <message-binding name="displayName" key="username"/> ④
    ??????????? <binding name="validator" expression="beans.requiredValidator"/> ⑤
    ??????????? <binding name="value" expression="username"/> ⑥
    ??????? </component>

    ??????? <component id="inputPassword" type="ValidField"> ⑦
    ??????????? <message-binding name="displayName" key="password"/>
    ??????????? <binding name="validator" expression="beans.requiredValidator"/>
    ??????????? <binding name="value" expression="password"/>
    ??????? </component>

    ??? </page-specification>
    ???

    Page-specification元素的class屬性和兩個(gè)property-specification元素與Pig Latin翻譯器應(yīng)用是相似的。

    你會發(fā)現(xiàn)第一個(gè)新東西-bean元素①,bean元素把一個(gè)org.apache.tapestry.valid.ValidationDelegate

    的實(shí)例指定了名稱"delegate"。頁面HTML模板里的Form控件把它的參數(shù)delegate設(shè)定為
    ognl:beans.delegate,就是指向了這個(gè)org.apache.tapestry.valid.ValidationDelegate實(shí)例。
    Bean元素②把一個(gè)org.apache.tapestry.valid.StringValidator的實(shí)例指定了名稱"
    requiredValidator",以用于驗(yàn)證。這個(gè)bean的required屬性被設(shè)為true表明使用這個(gè)bean的域是必須被驗(yàn)證的。這個(gè)bean的clientScriptingEnabled屬性被設(shè)定為ture,表明使用這個(gè)bean的域客戶端的JavaScript驗(yàn)證功能是激活的。RequiredValidator bean被用于驗(yàn)證inputUsername和inputPassword的內(nèi)容。

    控件inputUsername③被控件規(guī)范聲明為ValidField,ValidField是一種用于Tapestry驗(yàn)證子系統(tǒng)的特殊版本的TextField控件。Message-binding元素被用于指定inputUsername控件的displayName參數(shù)的值,這個(gè)值是用"username"為關(guān)鍵字從login.properties④文件里得到。InputUsername控件的validator參數(shù)被設(shè)定為requiredValidator bean,這是我們在頁面規(guī)范里聲明過的⑤。控件的value參數(shù)跟頁面Java類的username屬性綁定在一起⑥。控件inputPassword的控件規(guī)范跟控件inputUsername幾乎相似,除了用于取得displayName的關(guān)鍵字和綁定的頁面Java類的屬性不同。

    通過使用ValidField控件和為表單(form)提供一個(gè)ValidationDelegate, 我們激活了Login表單的驗(yàn)證功能。除了服務(wù)器端的驗(yàn)證,Tapestry也提供了客戶端的驗(yàn)證(利用JavaScript)。下面就是當(dāng)用戶提交一個(gè)表單而沒有為UserName域提供值時(shí),一個(gè)JavaScript錯(cuò)誤對話框彈出時(shí)的屏幕抓圖。

    /Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226287.jpg

    下面就是當(dāng)用戶提交一個(gè)表單而沒有為Password域提供值時(shí),一個(gè)JavaScript錯(cuò)誤對話框彈出時(shí)的屏幕抓圖。


    /Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226289.jpg


    下面就是Login頁對應(yīng)的Java 類。

    Login.java
    ??? package com.ociweb.tapestry;

    ??? import org.apache.tapestry.html.BasePage;
    ??? import org.apache.tapestry.IRequestCycle;
    ??? import org.apache.tapestry.valid.ValidationConstraint;
    ??? import org.apache.tapestry.valid.IValidationDelegate;

    ??? public abstract class Login extends BasePage {
    ??????? public abstract String getUsername();
    ??????? public abstract void setUsername(String username);

    ??????? public abstract String getPassword();
    ??????? public abstract void setPassword(String password);

    ??????? public void login(IRequestCycle cycle) {
    ??????????? String username = getUsername();
    ??????????? String password = getPassword();
    ??????????? StringBuffer sb = new StringBuffer(username);
    ??????????? String validPassword = sb.reverse().toString();
    ??????????? if (password.equals(validPassword)) {
    ??????????????? cycle.activate("Success");①
    ??????????? } else {
    ??????????????? String errorMessage = getMessage("invalidpassword");②
    ??????????????? IValidationDelegate validationDelegate =
    ??????????????????????? (IValidationDelegate) getBeans().getBean("delegate");③
    ??????????????? validationDelegate.record(errorMessage,
    ????????????????????????????????????????? ValidationConstraint.CONSISTENCY);④
    ??????????? }
    ??????? }
    ??? }
    ???
    跟Pig Latin翻譯器應(yīng)用一樣,我們的頁面類也是抽象的,它有抽象方法訪問在頁面規(guī)范里定義的屬性(properties)。Tapestry會在運(yùn)行時(shí)刻創(chuàng)建username和password屬性。Login方法只是簡單的驗(yàn)證一下用戶輸入的密碼值是否剛好是用戶名的反向。如果密碼通過驗(yàn)證,用戶將被引領(lǐng)導(dǎo)Success page①。

    如果密碼輸入有誤,我們用關(guān)鍵字"invalidPassword"通過從org.apache.tapestry.AbstractComponent里繼承來的getMessage()方法從Login.properties②里查找對應(yīng)的資源。我們需要把密碼錯(cuò)誤信息紀(jì)錄到我們在頁面規(guī)范中定義的頁面validation delegate中去。我們可以利用我們在頁面規(guī)范中指定的名稱,從頁面的beans屬性中找回validationDelegate③。最后,我們調(diào)用org.apache.tapestry.valid.IvalidationDelegate的record方法把將要顯示給用戶看的錯(cuò)誤信息保存起來。下面就是當(dāng)用戶輸入錯(cuò)誤密碼的提交后的屏幕抓圖。

    /Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-152262811.jpg

    下面就是Success頁的頁面模板。Success頁的頁面模板僅僅包含HTML標(biāo)識,所以它不需要頁面規(guī)范和頁面

    Java類。

    Success.html
    ??? <html>
    ??? <head>
    ??????? <title>Successful Login</title>
    ??? </head>
    ??? <body>
    ??????? <p>
    ??????????? Congratulations! You have successfully logged on.
    ??????? </p>
    ??? </body>
    ??? </html>
    ???
    總結(jié)

    我希望這篇文章已經(jīng)向你展示了Tapestry框架在構(gòu)建Web應(yīng)用的是多么簡單,然而優(yōu)雅。Tapestry與大多數(shù)主流Web應(yīng)用框架最大不同在于它讓你用基于控件的方式開發(fā),而非以操作為中心的方式開發(fā)。如果這篇文章激起了你的興趣,我建議你把它下載下來利用它你自己的簡單的Web應(yīng)用。通過感受簡單的應(yīng)用,這是你了解這個(gè)框架的優(yōu)點(diǎn)的唯一途徑。如果你想在你的下一個(gè)項(xiàng)目里使用Tapestry,我強(qiáng)烈建議你購買
    Tapestry In Action 這本書。我擁有這本書,對它我感到很滿意。

    References
    1 Zip file with all source code and war files from the article. (12K)

    ???????????????? http://www.ociweb.com/jnb/jnb2004_05.zip
    2 Tapestry Home Page http://jakarta.apache.org/tapestry/
    3 Tapestry In Action Page http://www.manning.com/lewisship/
    4 Tapestry Wiki http://jakarta.apache.org/tapestry/wiki_frame.html
    5 OGNL page http://www.ognl.org/
    6 Tapestry Component Reference

    ???????????????? http://jakarta.apache.org/tapestry/doc/ComponentReference/index.html
    7 Tapestry Component Workbench http://www.t-deli.com/app
    8 Designing Tapestry Mega-Components

    ???????????????? http://www.onjava.com/pub/a/onjava/2001/11/21/tapestry.html


    注:原文地址:http://www.inspiresky.com/Article/java/2006-02-14/412.html

    Feedback

    # re: [轉(zhuǎn)]Tapestry入門(譯作)  回復(fù)  更多評論   

    2007-08-09 18:23 by dreamstone
    幾個(gè)開源的web框架,就這個(gè)沒碰過,呵呵。
    不知道是否好用

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     

    posts - 2, comments - 1, trackbacks - 0, articles - 1

    Copyright © 壽業(yè)勇

    我要啦免费统计
    主站蜘蛛池模板: 午夜免费啪视频在线观看| 国产V片在线播放免费无码| 2019中文字幕免费电影在线播放| 亚洲精品无码专区久久同性男| a毛片全部播放免费视频完整18| 大胆亚洲人体视频| 免费国产黄网站在线观看动图| 免费中文字幕在线观看| 伊人久久国产免费观看视频| 亚洲国产一区二区视频网站| 国产免费内射又粗又爽密桃视频| 亚洲国产精品特色大片观看完整版| 国产免费拔擦拔擦8X高清在线人 | 亚洲综合激情九月婷婷| 亚洲毛片免费视频| 亚洲精品123区在线观看| 日韩成人在线免费视频| 免费人成大片在线观看播放电影| 久久精品国产精品亚洲| 亚洲免费人成在线视频观看 | 91精品国产免费| 亚洲国产综合精品| 四虎在线视频免费观看| 美女视频黄.免费网址| 中文字幕中韩乱码亚洲大片| 国产免费无码AV片在线观看不卡| 亚洲国产精品日韩在线| 国产一区二区视频免费| 中文在线免费视频| 亚洲国产成人va在线观看网址| 日韩电影免费在线| 97人妻精品全国免费视频 | 亚洲人成网站在线观看播放动漫| 日本不卡视频免费| 久久成人18免费网站| 亚洲精品国产第1页| 国产91久久久久久久免费| 亚在线观看免费视频入口| 亚洲午夜无码久久久久小说| 国内精品99亚洲免费高清| 99久久免费国产精品特黄|