Tapestry 是基於 Servlet 的組件化 Web 框架,將開發者從繁瑣的 Request/Response 模式中解脫,專注於頁面、組件、事件、對象。本文以 Tapestry 4.1.2 為例,從環境搭建到計數器實戰,帶你快速上手。
lib 下 JAR 複製到 WEB-INF/libcommons-logging.jar、javassist.jar、ognl-2.6.11.jarweb.xml 註冊中央控制器:
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
-Dorg.apache.tapestry.disable-caching=true,開發期修改模板即時生效WebRoot 下建 Home.html,訪問 /app 自動渲染(約定大於配置)。
<span jwcid="@Insert" value="ognl:new java.util.Date()"></span>
jwcid = Java Web Component ID,@Insert 組件輸出值,OGNL 表達式動態計算。
<a href="#" jwcid="@PageLink" page="Home">刷新</a>
框架自動生成指向 Home 頁面的 URL,無需手寫。
Home.html:
<span jwcid="@Insert" value="ognl:counter"></span>
<a href="#" jwcid="@DirectLink" listener="listener:doClick">計數器增1</a>
Home.java(包路徑需在 app.application 配置):
public abstract class Home extends BasePage {
@Persist
public abstract int getCounter();
public abstract void setCounter(int count);
public void doClick() {
setCounter(getCounter() + 1);
}
}
app.application:
<application>
<meta key="org.apache.tapestry.page-class-packages" value="com.bjsxt.crm.web.tapestry.test"/>
</application>
關鍵點:@Persist 讓屬性跨請求保持(默認存 Session),DirectLink 觸發 listener:方法名(不帶括號)。
<a href="#" jwcid="@DirectLink" listener="listener:doClick" parameters="ognl:5">計數器增5</a>
<a href="#" jwcid="@DirectLink" listener="listener:clearCounter">清空計數器</a>
頁面類新增 doClick(int increment)、clearCounter() 方法,參數自動綁定。
| 概念 | 說明 |
|---|---|
| Page | .html 模板 + .java 類(可選),一一對應 |
| Component | 可復用 UI 片段,如 @Insert、@PageLink、@DirectLink |
| OGNL | 對象圖導航語言,綁定屬性、調用方法、集合操作 |
| @Persist | 頁面屬性持久化(Session/Client/Workflow) |
| Listener | 事件監聽器,命名約定 listener:方法名 |
| Application Spec | app.application XML,配置頁面類包路徑、全局屬性 |
Tapestry 4.x 已停止維護,現代項目建議選用 Tapestry 5.4+(重寫核心、支持注解、無 XML 配置)或 Spring MVC、Spring Boot 等主流框架。本文僅供維護舊項目或學習組件化思想參考。