Tapestry 登录应用

Tapestry  登录应用

你在Pig  latin翻译器应用中看到了Tapestry的一些基本特性。与其用一个复杂的应用展示Tapestry所有的特性以致于压得你揣不过气来,还不如通过一些简单的应用让你找到一点对Tapestry的感觉。下面这个应用展示Tapestry如何处理页面导航,区域化,验证和其他一些特性。

这里有一个Home页的屏幕抓图,下面跟着它的页面模板。



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>
       
这个Home页的页面模板除了一个jwcid属性定义使用一个Tapestry  PageLink①控件以外都是标准的HTML。

PageLink控件生成了一个指向Login页的超链接。既然Home页没有任何动态的行为所以它不需要页面规范和页面对应的Java类。

这里是Login页的屏幕抓图,后面跟着是它的页面模板。

 

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>
       

这个页面模板大多数是通常的HTML。我们从页面模板中可以看到Tapestry的区域化特性:它使用一个span元素,这个span元素带有一个叫key的属性,key的值映射到Login.properties文件里一个属性。一个Body控件被声明使用,因为它对客户端的JavaScript校验是必需的。

为Form  component⑤设定delegate属性激活表单输入验证。delegate属性是我们在页面规范里声明的org.apache.tapestry.valid.IvalidationDelegate的实现类。如果验证错误发生了,我们用Conditional  component③控件判断delegate是否有任何错误,如果有就把第一个错误④显示给用户。如果ognl  表达式ognl:beans.delegate.hasErrors  为true,Conditional控件将显示它的内容实体。所有的页面类和控件类都从AbstractComponent继承来一个叫beans的属性。这个beans属性是一个org.apache.tapestry.IbeanProvider的实例,利用它可以通过名字取得在页面规范文件里定义的beans.FieldLabel⑥被用于为inputuserName  validField控件显示标签,这个FieldLabel控件也被用来与表单的验证代理协作,指出包含错误的输入域。
InputUserName⑦控件是一个显示控件的例子。显式控件是指在页面规范文件声明的控件。InputUsername和inputPassword控件都是显式的,它们与FieldLabel联合显示它们的displayName属性。

下面的是Login页的资源文件。Login.properties跟页面规范一并存放在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属性和两个property-specification元素与Pig  Latin翻译器应用是相似的。

你会发现第一个新东西-bean元素①,bean元素把一个org.apache.tapestry.valid.ValidationDelegate

的实例指定了名称"delegate"。页面HTML模板里的Form控件把它的参数delegate设定为
ognl:beans.delegate,就是指向了这个org.apache.tapestry.valid.ValidationDelegate实例。
Bean元素②把一个org.apache.tapestry.valid.StringValidator的实例指定了名称"  
requiredValidator",以用于验证。这个bean的required属性被设为true表明使用这个bean的域是必须被验证的。这个bean的clientScriptingEnabled属性被设定为ture,表明使用这个bean的域客户端的JavaScript验证功能是激活的。RequiredValidator  bean被用于验证inputUsername和inputPassword的内容。

控件inputUsername③被控件规范声明为ValidField,ValidField是一种用于Tapestry验证子系统的特殊版本的TextField控件。Message-binding元素被用于指定inputUsername控件的displayName参数的值,这个值是用"username"为关键字从login.properties④文件里得到。InputUsername控件的validator参数被设定为requiredValidator  bean,这是我们在页面规范里声明过的⑤。控件的value参数跟页面Java类的username属性绑定在一起⑥。控件inputPassword的控件规范跟控件inputUsername几乎相似,除了用于取得displayName的关键字和绑定的页面Java类的属性不同。

通过使用ValidField控件和为表单(form)提供一个ValidationDelegate,  我们激活了Login表单的验证功能。除了服务器端的验证,Tapestry也提供了客户端的验证(利用JavaScript)。下面就是当用户提交一个表单而没有为UserName域提供值时,一个JavaScript错误对话框弹出时的屏幕抓图。



下面就是当用户提交一个表单而没有为Password域提供值时,一个JavaScript错误对话框弹出时的屏幕抓图。





下面就是Login页对应的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翻译器应用一样,我们的页面类也是抽象的,它有抽象方法访问在页面规范里定义的属性(properties)。Tapestry会在运行时刻创建username和password属性。Login方法只是简单的验证一下用户输入的密码值是否刚好是用户名的反向。如果密码通过验证,用户将被引领导Success  page①。

如果密码输入有误,我们用关键字"invalidPassword"通过从org.apache.tapestry.AbstractComponent里继承来的getMessage()方法从Login.properties②里查找对应的资源。我们需要把密码错误信息纪录到我们在页面规范中定义的页面validation  delegate中去。我们可以利用我们在页面规范中指定的名称,从页面的beans属性中找回validationDelegate③。最后,我们调用org.apache.tapestry.valid.IvalidationDelegate的record方法把将要显示给用户看的错误信息保存起来。下面就是当用户输入错误密码的提交后的屏幕抓图。



下面就是Success页的页面模板。Success页的页面模板仅仅包含HTML标识,所以它不需要页面规范和页面

Java类。

Success.html  
       <html>
       <head>
               <title>Successful  Login</title>
       </head>
       <body>
               <p>
                       Congratulations!  You  have  successfully  logged  on.
               </p>
       </body>
       </html>
       
总结

我希望这篇文章已经向你展示了Tapestry框架在构建Web应用的是多么简单,然而优雅。Tapestry与大多数主流Web应用框架最大不同在于它让你用基于控件的方式开发,而非以操作为中心的方式开发。如果这篇文章激起了你的兴趣,我建议你把它下载下来利用它你自己的简单的Web应用。通过感受简单的应用,这是你了解这个框架的优点的唯一途径。如果你想在你的下一个项目里使用Tapestry,我强烈建议你购买
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 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值