不必关心链接!不必关心请求 (http request) 到了哪里!不必关心响应 (http response) 要转向哪里! Tapestry 构建于底层的 request-resonse 模式,基于 Servlet 技术,抽象出面向组件开发的模型。 Tapestry 关心的是:页面、组件、事件、对象、方法、属性 !
1 、
将 Tapestry 解压目录下的 lib 目录中的 jar 包拷贝到 WEB-INF/lib 目录。
并将重复的包删除( commons-logging.jar/javassist.jar/ognl-2.6.11.jar )
2 、
在 web.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 > |
这是 Tapestry 的中央控制器。 Tapestry 页面的显示,所有的请求,都会被发送到这个 Servlet 上。
在 WebRoot 下添加 Home.html
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=GB18030" > < title > Insert title here </ title > </ head > < body > 第一个 Tapestry 程序 </ body > </ html > |
并访问网址:
http://localhost:8088/[context path]/app |
结果页面显示 Home.html 里面的内容。
这是因为 Tapestry 总是会包含一个名字叫 ”Home” 的页面,默认情况下就是根路径下的 Home.html
Home.html 改为:
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=GB18030" > < title > Insert title here </ title > </ head > < body > 第一个 Tapestry 程序 现在时间是: <span jwcid="@Insert" value="ognl:new java.util.Date()"> </span> </ body > </ html > |
重新访问网址: http://localhost:8088/[context path]/app
在这个页面上,用到了 Tapestry 的 Insert 组件( Component )。它带一个参数,通过一个 ognl 表达式来传递。
在应用服务器的启动参数中添加: -Dorg.apache.tapestry.disable-caching=true ,可以避免每次修改页面模板的时候重启服务器。
jwc = Java Web Component
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=GB18030" > < title > Insert title here </ title > </ head > < body > 第一个 Tapestry 程序 现在时间是: < span jwcid = "@Insert" value = "ognl:new java.util.Date()" ></ span > < p > <a href="#" jwcid="@PageLink" page="Home"> 刷新 </a> </ body > </ html > |
这次,通过一个 PageLink 组件,指向 Home 页面, PageLink 组件会自动产生指向 Home 页面的链接(我们不必关心这个链接!)。
直到现在为止,我们还没有涉及到 java 类,但是已经让 Tapestry 成功运行起来了!该是写点 java 代码的时候了。我们想要创建一个计数器,每当用户点击“计数器增 1 ”的时候,我们将这个计数器加 1 ,然后在页面上显示出这个结果。
在传统的请求 - 响应模式中,我们针对这个问题,需要考虑的是:递交一个请求,创建相应的 Action 来接收这个请求,并维护计数器的值,然后决定成功转向的页面,将结果显示在页面上。
在 Tapestry 中,我们需要考虑的是:在哪个页面处理这个事件,结果如何显示在页面上?
下面是 Home.html
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=GB18030" > < title > Insert title here </ title > </ head > < body > 第一个 Tapestry 程序 现在时间是: < span jwcid = "@Insert" value = "ognl:new java.util.Date()" ></ span > < p > < a href = "#" jwcid = "@PageLink" page = "Home" > 刷新 </ a > < p > 计数器当前的值是: <span jwcid="@Insert" value="ognl:counter"></span> <a href="#" jwcid="@DirectLink" listener="listener:doClick"> 计数器增 1</a> </ body > </ html > |
DirectLink 指定的 listener 为: doClick ,这将触发一个事件,实际上就是将要调用 doClick() 方法。
doClick() 方法将要写在哪里?因为现在的页面,其动态数据无法简单获得,所以,必须给当前页面创建一个对应的类,我们的方法将创建在这个类里面。
package com.bjsxt.crm.web.tapestry.test;
import org.apache.tapestry.annotations.Persist; import org.apache.tapestry.html.BasePage;
public abstract class Home extends BasePage {
@Persist public abstract int getCounter(); public abstract void setCounter(int count);
public void doClick(){ int counter = getCounter(); counter = counter + 1; setCounter(counter); } } |
注意 :在这个例子中,类名需定义为 Home ; listener 的名字为 doClick ,而不是 doClick()
另外,需要在 web-inf 目录下添加配置文件: app.application
<?xml version="1.0"?>
<!DOCTYPE application PUBLIC "-//Apache Software Foundation//Tapestry Specification 4.0//EN" "http://tapestry.apache.org/dtd/Tapestry_4_0.dtd" >
<application> <meta key = "org.apache.tapestry.page-class-packages" value = "com.bjsxt.crm.web.tapestry.test" /> </application> |
配置的主要目的是让 Tapestry 了解如何关联页面和页面类。
Home.html 改为:
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=GB18030" > < title > Insert title here </ title > </ |