欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(转载)Tapestry最新版5.1.0.5教程(三)

程序员文章站 2022-07-15 15:13:51
...
    在讲述页面之间传递值之前首先要介绍一个Tapestry的页面缓存。
    Tapestry的一个经常被提及的就是页面的缓存,Wicket也有页面缓存,但是Wicket的页面是缓存在Session里的,缺省好像是只缓存5个页面。这一点让我对Wicket的印象打了折扣,首先,这种机制在高并发,也就是多人同时在线的时候,感觉页面缓存会占用大量资源。而Tapestry的页面缓存是在一个大池中。
    页面缓存的优点就是提高效率,但是缺点也是比较明显的,那就是给开发实现带来了不方便。我觉得众人说的Tapestry的学习曲线比较陡,一部分原因就在这里。上一章讲过,在Tapestry中,页面的跳转是通过InjectPage实现的。Tapestry在页面跳转时,会从缓存池中选取一个相应页面的实例,渲染成html。关键在于Tapestry在把页面放到缓存池之前,会把页面实例里的值清空。这就是造成页面传值麻烦的原因。写段代码示例:
class Register {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

class Start{
    @InjectPage
    private Register register;

    Object onSubmit() {
        register.setName("superman");
        return register;
    }
}

    如果页面从Start跳转到Register,并且希望把superman这个值传递给Register这个页面,感觉上只要象上面这段代码一样简单设置一下就行了,但是实际上这样是无法在Register的页面上显示出superman这个名字的。因为Tapestry会在页面显示时候的时候,从缓存池中提取一个实例,这个实例在放入缓存池之前,name属性的值就被清空了。

下面是Tapestry页面之间传递值的几种方式:
1、Persist。最简单的方式是使用persist注解。
class Register {
    @Persist
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

   只要这样指定后,Tapestry会把name的值保存在Session中,以备下次使用。但是这样的缺点也很明显,首先是占用资源,另外这样的URL是不能作为书签的,因为参数值不体现在URL中,而是保存在Session中。

2、Page Active Context。这个方法比较好,但是需要一些代码来实现。主要是添加两个函数onActivate和onPassivate。
Class Register {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    void onActivate(String name) {
        this.name = name;
    }
    String onPassivate() {
        return name;
    }
}

    在Start页面中,我们使用了InjectPage把Register注入到了类中,如果只是简单地返回Register,是不能正确显示name的值的,但是在Tapestry会在把Start页面中的Register放回缓存池,清空Register实例中的变量值之前,检查这个类是否存在,但是现在我们实现了onActivate和onPassivate这两个方法,Tapestry会自动将onPassivate返回值保存起来,然后从页面池中取得页面后,再把刚才保存的值作为参数传递给onActivate方法。

3、SessionState
    在Tapestry中有一种类型的对象存储在Session中,所以对所有页面都是可见的,但是又不需要对页面暴露Session。在Tapestry5以前,称之为ApplicationStateObject,但是这个称呼并不准确,因为这个对象不是Application级别,而只是Session级别,所以Tapestry5开始,改名为SessionStateObject。
    使用方法也很简单,只需要在JavaClass中,给相应的属性添加一个@SessionState注解即可。
    需要提醒注意的是,SessionState区分对象实例不依赖于实例的名称,而是根据实例的类型,比如:你在一个类中使用@SessionState注解了一个String name;而在另一个类中想再用@SessionState注解一个String password;这是不行的,Tapestry会把这两个当作同一个对象实例。
    另一个需要注意的是,SessionState注解之后,Tapestry会马上会初始化生成一个该对象的实例。

原文地址:[url]http://www.blogjava.net/usherlight/archive/2009/06/05/280207.html [/url]