页面跳转类组件:ActionLink, DirectLink, ExternalLink, GenericLink, ServiceLink

1-ActionLink组件

 

暂时理解为,不转向下一页面,只是激活一个监听方法。

页面响应时,创建了一个链接。如果触发了链接时,组件ActionLink得到一个监听器(通过调用方法actionTriggered())。

2-DirectLink组件

-------------------------------------------------------------------------------------------------------------------

1-DirectLink创建一个<a/>标签,该链接包含了一些提供给组件监听方法的上下文环境数据,它被用在当ActionLink不好用的时候。

2-parameters参数指明了一个对象数组,被编码到url上面,当链接被触发的时候,这些对象将会被解码。意思就是可以将“对象”做为参数传递。

监听方法可以通过3种方法取得参数:

1-istenerMethod(parameters) :就是在监听方法中,提供参数

2-istenerMethod(IRequestCycle cycle, parameters)

3- listenerMethod(IReuqestCycle cycle), using IRequestCycle.getServiceParameters()

3-stateful参数为true的时候,当链接被激活的时候,会检查有没有合法的HttpSession如果不能拿到就会抛出 StaleLinkException异常。

我不知道你是否觉得有些特别:Tapestry能够将对象通过URL进行页面之间的传递,或者将一个对象完整地保存到客户端的浏览器上。我以前做的项目里面,传递的URL甚至长达一千多个字符。

回想一下在JSP里面,页面与页面之间参数的传递,全部都是String类型的,除非你放在Session中进行传递。而Tapestry却可以传递对象。为什么呢?

其实原因很简单,正如同你先前看见的错误:Could not find an adaptor for class com.ramon.test.MyObj。也就是说,Tapestry仍然是传递String类型的参数,保存在客户端浏览器上的也仍然是 String。作为一个框架,Tapestry将你需要传递的对象转换了一遍,也就是说,通过一个“适配器(adaptor)”,在服务器端将一个对象转 换为一段唯一的String,放到客户端浏览器上,当从客户端将这段String字符串返回到服务器段的时候,Tapestry又会将其还原为原先的对 象,并保留了该对象的状态。

而你提到的“为什么DirectLink并没有提到序列化?”,因为序列化的目的就是为了在数据传输过程中保存对象的状态。序列化是一门非常庞大的学问,当然,也可以简单地片面解释为数据传输的一种规范。既然作为一种规范,有时候可能也就忽略不提了。

关于Tapestry的这个adaptor,在Tapestry4.0中,就可以按照自己的逻辑对官方提供adaptor进行重构。记得大概在 Tapestry4.0-beta5之前,官方没有为T4提供adaptor,那个时候,在Tapestry的官方邮件列表里面,达人们就自己实现 adaptor。


persit="client" 是否要谨慎使用,虽然用起来很爽
我个人觉得对于大对象,是不合适的。该page中的XXXXLink都会有一个参数state:PageName=xxxxxxxx(非常长)。我碰到的问题是,因为GET方式对URL长度的限制,加了那些参数的链接是打不开的。

可能可以用其他方式来避免。但是我觉得最好是小对象,比如个把ID的传输还是很合适的。


实际上你多虑了,你可以仔细看看页面运行的源代码,如果是xxxLink,都是以post方式传递的。下面是我以前在T3时代用DirectLink的一个URL。
是我们【成都建信】www.cdcin.com实际在运行的项目中的一个链接。用word进行数字统计:741 ,当然,这并不是我们最长的链接。

http://www.cdcin.com/Work_safety_constructionFinishForm.html?sp=OH4sIAAAAAAAAAFvzloG1uIhBKTk_Vy85JTe5WC8_US8pX885P6-4pKg0uSQzP88tMy-zOONyjYkuy7Y_B5kYGCqKGLTRNSQlFqfqOQEJTJ3f_X1PPloh08DEwOnJwJGRWJzhnJ-S6sPAHZ-YnJxaUOKSWJJawiDgk5VYlqhfWpKZow8SsQYrKCjJLClNSfXLL2EQgijIScxL1w8uKcrMSwcq4YsHOiQ3s8Q5P7cgMa-ykKGOgdmHQQQoinAFqhx7fFpmDtBAKJc5PjOlhEEYyWzPvJLU9NQioOE88QVF-VmpySWOKSlFUPVwMb_E3FSwWEVBAwMDAzAQeUFm6BUX5uiB3C_yyy3D3jRtOiS8-MByIM-BJTOyGhm9I0skmYGSBeUcQP3_HeatYKgoYeA0MjAwNjSwMDQtYVB81jHhZfPepzuanq9Z87R19dPdu56vnfh0-9LnK7qftq552r-jhEEdqqZ31vOJ85517H86Z8OTXcuf7ml42j_x2ZzOlzMnwFSCTDYxNDCxsAC6VRDsHpB_9aD-FXq0YMn3xnYLJgZGTwbWssSc0lSguwUQ6vxKc5NSi9rWTJXlnvKgG-StAgYGxuvAiHk5d9LzfV1Plyx_2TjZ0MDwaf_2EgZZiIsgzn_RtfHp7LVPdnQ-mzPfGCQPABoE4-93AgAA

虽然这个链接中没有state数据,但是至少可以证明,URL是可以很长的。
那么你所说的GET方式,也就是以Form形式提交的时候。而此时persist的state数据,是以表单的一个hidden放在Form中的。

因此,我认为不会存在你所提的这种情况。


--------------------------------------------------------------------------------------------------------------------

DirectLink组件涉及到session,与ExternalLink组件的区别有两个:

  第一: DirectLink涉及sessionDirectLink拥有一个boolean类型的stateful参数来选择statefulstateless,该参数默认为true,即stateful

ExternalLink却不涉及sessionExternalLink仅仅是stateless,不能够选择。

  第二:非常重要的是,DirectLinkExternalLink参数传递方式不一样。

  DirectLink---->在本页面的监听方法中获取参数,然后将参数设置到下一个页面。

  ExternalLink---->通过在下一个页面实现IExternalPage接口以及activateExternalPage方法“接收”参数。

  为了实现分页功能,我们使用DirectLink组件实现。在下面的例子,每个页面我们只显示10条数据,那么HQL就只从数据库中查询出10条数据。对于页面来说,就需要实现“下一页”(或“上一页”)页面跳转,以及向我们的业务逻辑层方法传递分页参数(即当前页码,以及每页显示数据数)。
请看对应的
HTML文件中相关代码: 
   <span jwcid="@Conditional" condition="ognl:firstDisable"> 
         <span jwcid="first">首页</span> 
         <span jwcid="previous">上一页</span> 
   
</span> 
   
<span jwcid="@Insert" value="ognl:pageNo" />  
   
<span jwcid="@Conditional" condition="ognl:lastDisable"> 
         <span jwcid="next">下一页</span> 
         <span jwcid="last">尾页</span> 
   </span> 
 共 <span jwcid="@Insert" value="ognl:total" />
page文件中声明相关组件:

需要在包含该链接的页面类中定义first previous next maxResult的getter和setter

   <component id="first" type="DirectLink"> 
   <binding name="listener" expression="listeners.changePage"/> 
   <binding name="parameters" expression="new java.lang.Object[]{first,maxResult}"/> 
 </component>
 <component id="previous" type="DirectLink"> 
   <binding name="listener" expression="listeners.changePage"/> 
   <binding name="parameters" expression="new java.lang.Object[]{previous, maxResult}"/>
   <binding name="disabled" expression="previousDisable"/>
 </component>
 <component id="next" type="DirectLink"> 
   <binding name="listener" expression="listeners.changePage"/> 
   <binding name="parameters" expression="new java.lang.Object[]{next, maxResult}"/> 
   <binding name="disabled" expression="nextDisable"/>
 </component>
 <component id="last" type="DirectLink"> 
   <binding name="listener" expression="listeners.changePage"/> 
   <binding name="parameters" expression="new java.lang.Object[]{last,maxResult}"/>
 </component>
  DirectLink组件表现为一个HTML<a>元素,用来提供一个URL,当用户点击时,触发页面中一个特定的监听方法。
  在实现分页页面跳转的四个组件里,都声明为同一个listener监听方法。请看相应java中的对应监听方法changePage的代码:
public void changePage(IRequestCycle cycle) { 
   //Tapestry4.0已经deprecated了cycle.getListenerParameters()
   Object[] parameters = cycle.getServiceParameters(); 
   //获取当前页码 
   Integer ig1 = (Integer) parameters[0]; 
   int i1 = ig1.intValue(); 
   setPageNo(i1); 
   //获取每页最大显示数目 
   Integer ig2 = (Integer) parameters[1]; 
   int i2 = ig2.intValue(); 
   setMaxResult(i2);
}
  对于DirectLink,parameters参数的赋值方式于ExternalLink一样。这里获取的是一个数组,这个数组包含了两样信息:即将跳转的页码数,以及即将跳转的页面显示多少条数据。
 
在 前面,我们提到过,页面的java文件在完成页面表现所需数据的处理后,应该将其所有成员变量(页面property)还原为初始值。所以,“当前页码” 以及“每页最大显示数据”这两个数据,我们将它们“保存”在页面上。当点击触发监听方法后,再由页面来提供下一个页面的“页码”和“每页最大显示数目”。 然后再查询新的maxResult条数据。
 
运行效果图如下:



3-ExternalLink组件

-----------------------------------------------------------------------------------------------------------------------------------------------
ExternalLink对于参数是采用“接收”的方式是指向本应用页面的Link。
ExternalLink组件不会验证用户session,因此ExternalLink组件生成的URL能够被用户收藏,以便再次访问。

<a href="#" 
jwcid="@ExternalLink"
page="ViewArticle"
parameters="ognl:{articleId, 'de'}"
disabled="ognl:languageCode=='de'"
>view this article in German</a>

<div jwcid="@Insert" value="ognl:content">content of the article</div>

package com.myexample;

import org.apache.tapestry.IExternalPage;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.html.BasePage;

public abstract class ViewArticle extends BasePage
implements IExternalPage {

public abstract Integer getArticleId();
public abstract void setArticleId(Integer articleId);
public abstract String getLanguageCode();
public abstract void setLanguageCode(String language);

public void activateExternalPage(Object[] params, IRequestCycle cycle) {
setArticleId((Integer) params[0]);
setLanguageCode((String) params[1]);
}

public String getContent() {
// retrieve the content of the article for the selected language

}

}
-----------------------------------------------------------------------------------------------------------------------------------------------

ExternalLink组件使用的是Tapestry9service中的external service。该组件使用External Service 创建继承了IExternalPage接口的一个链接。下面用一个例子说明它的用法。
<a jwcid="@ExternalLink" page="SuccessPage" parameters='ognl:new java.lang.Object[]{"This is Success Page!", item.id}'disabled="ognl:item.Isable"></a>
page="SuccessPage"这个参数的作用,就是指定了将要跳转的页面名称,ExternalLink组件的page参数根据配置文件tapestry.application文件中的配置找到对应的page文件
<page name="SuccessPage" specification-path="/WEBINF/SuccessPage.page"/>
然后在SuccessPage.page文件中,根据:
<page-specification class="com.ce.tapestry.Success">
找到对应的Success.java文件。在Success.java文件中,我们发现该类继承了IExternalPage接口:
public abstract class Success implements IExternalPage
以及实现了activateExternalPage(Object[]IRequestCycle)方法。
 
对于ExternalLink组件,它必须继承IExternalPage接口,并实现public void activateExternalPage(Object[] parameters,IRequestCycle cycle)方法。该方法的参数Object[]来自该组件的parameters参数的值。 disabled参数默认为false,当为true时,不能被“点击”。

4-GenericLink组件

组件GenericLink通常用于跳转到应用程序范围以外的链接 虽然GenericLink可以用其他组件也能完成,但是GenericLink更灵活:它可以设置为disabled,象DirectLink或者ActionLink一样也能包含Rollover组件
使用方法如下:
<a jwcid="@GenericLink" href="ognl:item.homepage" disabled="false"/>
Href参数:其作用很明显,就是提供一个链接地址。从上例可知:从item.homepage取出地址。
disabled参数:该参数默认为false,当为true时,不能被“点击”。关于disabled参数,所有link类组件都有,作用均相同。

5-PageLink组件

相当于不带参数的ExternalLink

PageLink组件非常简单,只需要在page参数中指明需要跳转到下一个页面的名字。不过需要注意的是,PageLinkExternalLink使用的不是同一个service该组件使用了Page Service创建了另外一个链接URL
使用方法请见例子:
<a jwcid="@PageLink" page="Infos"><img src="images/lyb.gif" width="50" height="18" border="0">
</a>
跳转到以下的URLhttp://localhost:8080/hello/helloworld?service=page/Upload

6-ServiceLink组件

创建任意不带有参数的引擎服务ServiceLink组件用法与ActionLinkPageLinkDirectLink等组件相似,但常常与具体的应用服务一起使用。Service参数是要调用的EngineService对象的名称。(Body

以上的Link类组件,都需要在Body组件范围内使用。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值