首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Tapestry 框架入門:基於元件的 Web 開發新範式

     編輯:Java 相關知識

背景:從 C/S 到 B/S 的演進與痛點

  • B/S 架構優勢:瘦客戶端、零部署、跨平台、易維護
  • 核心缺點:HTTP 無狀態、程式碼與 HTML 混雜(維護噩夢)、缺乏像 C/S 那樣豐富的元件模型
  • Struts 雖實現 MVC、引入 Taglib,但仍未徹底分離邏輯與視圖,Taglib 無法繼承,學習曲線陡峭

Tapestry 核心優勢

  • 極高程式碼復用: 一切皆元件
  • 真正面向物件: 脫離 URL 解析,回歸 OO 設計
  • 完整國際化支援
  • 精確錯誤定位: 直指原始碼行號,非 JSP 模糊異常
  • 團隊協作友善: 美工與工程師互不依賴,並行開發

Tapestry 元件結構:三位一體

一個 JWC (Java Web Component) 包含:

  1. HTML 模板:近乎純 HTML,僅加 jwcid 屬性標記元件位置
  2. XML 定義檔:連結模板與 Java 類,宣告元件屬性綁定
  3. Java 類:繼承 BasePage 或 BaseComponent,提供邏輯與資料

Hello World 完整範例

Home.html(模板)

<html>
<head><title>Welcome to Tapestry!</title></head>
<body>
Hello <span jwcid="user">User Name</span>! Welcome to Tapestry!
</body></html>

jwcid="user" 表示此處插入名為 user 的元件。<span> 不影響版面,利於美工使用 Dreamweaver/FrontPage。

Home.page(定義檔)

<page-specification class="demo.Home">
  <component id="user" type="Insert">
    <binding name="value" expression="userName"/>
  </component>
  <context-asset name="$template" path="Home.html"/>
</page-specification>
  • id 對應模板 jwcid
  • type="Insert" 為內建元件,將值插入模板
  • expression="userName" 透過 OGNL 綁定 Java 類的 userName 屬性

Home.java(邏輯類)

package demo;
import org.apache.tapestry.html.BasePage;
public class Home extends BasePage {
    private String userName = "Jack";
    public String getUserName() { return this.userName; }
}

實際執行時,OGNL 讀取 getUserName() 回傳值,更新 Insert 元件的 value,最終輸出 "Jack"。

Application 設定檔

<application name="Tapestry Illustration 1">
  <page name="Home" specification-path="Home.page"/>
</application>

web.xml 註冊 ApplicationServlet

<servlet>
  <servlet-name>Welcome</servlet-name>
  <servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
  <load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>Welcome</servlet-name>
  <url-pattern>/app</url-pattern>
</servlet-mapping>

訪問 https://localhost:8080/Welcome/app 即見成果。

進階範例:使用者註冊與 DatePicker 元件

CustInfo.html(隱式元件定義)

<html jwcid="@Shell" title="Welcome Page">
<body jwcid="@Body">
<form jwcid="@Form" listener="ognl:listeners.submit">
  Customer Name: <input jwcid="custName" type="text"/><br/>
  Date-of-Birth: <input jwcid="dob" type="text" format="MMM dd, yyyy"/><br/>
  <input type="submit" value="Submit"/>
</form>
</body></html>

@Shell, @Body, @Form 為隱式元件,無需在 .page 定義,參數直接寫在模板。

CustInfo.page(顯式元件定義)

<page-specification class="demo.Welcome">
  <property-specification name="custName" type="java.lang.String"/>
  <property-specification name="dob" type="java.util.Date"/>
  <component id="custName" type="TextField">
    <binding name="value" expression="custName"/>
  </component>
  <component id="dob" type="DatePicker">
    <binding name="value" expression="dob"/>
  </component>
</page-specification>
  • property-specification 讓 Tapestry 自動產生 getter/setter,Java 類只需宣告 abstract 方法
  • DatePicker 核心元件自動產生彈出式日期選擇 UI,零 JavaScript 成本

Welcome.java(抽象類,Tapestry 代碼生成實作)

public abstract class Welcome extends BasePage {
    public abstract void setCustName(String custName);
    public abstract void setDob(Date dob);
    public abstract String getCustName();
    public abstract Date getDob();

    public void submit(IRequestCycle cycle) {
        if (getCustName() != null && !getCustName().trim().equals("") && getDob() != null) {
            Welcome welcome = (Welcome) cycle.getPage("Welcome");
            welcome.setCustName(getCustName());
            welcome.setDob(getDob());
            cycle.activate(welcome); // 頁面跳轉
        }
    }
}

listener="ognl:listeners.submit" 綁定 submit 方法,IRequestCycle 控制頁面流程。

總結

Tapestry 以元件化思維重塑 Web 開發:HTML 模板純淨、XML 定義清晰、Java 類專注邏輯。內建豐富元件庫(含 DatePicker、Foreach 等控制元件),支援自訂元件繼承組合。開源社群活躍,原始碼可讀性高,適合追求可維護性、團隊協作與豐富 UI 的企業級專案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved