云自無心水自閑

          天平山上白云泉,云自無心水自閑。何必奔沖山下去,更添波浪向人間!
          posts - 288, comments - 524, trackbacks - 0, articles - 6
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          Tapestry最新版5.1.0.5教程(三)

          Posted on 2009-06-05 14:24 云自無心水自閑 閱讀(2731) 評論(0)  編輯  收藏 所屬分類: Java 、心得體會 、Tapestry

          在講述頁面之間傳遞值之前首先要介紹一個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頁面之間傳遞值的幾種方式:
          2、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中。
          3、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會自動
          4、SessionState
          在Tapestry中有一種類型的對象存儲在Session中,所以對所有頁面都是可見的,但是又不需要對頁面暴露Session。在Tapestry5以前,稱之為ApplicationStateObject,但是這個稱呼并不準確,因為這個對象不是Application級別,而只是Session級別,所以Tapestry5開始,改名為SessionStateObject。
          使用方法也很簡單,只需要在JavaClass中,給相應的屬性添加一個@SessionState注解即可。
          需要提醒注意的是,SessionState區分對象實例不依賴于實例的名稱,而是根據實例的類型,比如:你在一個類中使用@SessionState注解了一個String name;而在另一個類中想再用@SessionState注解一個String password;這是不行的,Tapestry會把這兩個當作同一個對象實例。
          另一個需要注意的是,SessionState注解之后,Tapestry會馬上會初始化生成一個該對象的實例。



          主站蜘蛛池模板: 仙居县| 金寨县| 峨眉山市| 正蓝旗| 泊头市| 钟山县| 平乐县| 淳化县| 湘潭县| 海淀区| 阳新县| 丰都县| 尖扎县| 孟村| 彰武县| 通化市| 大名县| 灵璧县| 讷河市| 广德县| 逊克县| 丰顺县| 潢川县| 寻乌县| 建瓯市| 繁昌县| 曲麻莱县| 广安市| 仙游县| 毕节市| 蕲春县| 白山市| 孟州市| 长治市| 林芝县| 桦南县| 乌兰浩特市| 白山市| 舒城县| 舟山市| 富蕴县|