简单介绍

不必关心链接!不必关心请求(http request)到了哪里!不必关心响应(http response)要转向哪里!Tapestry构建于底层的request-resonse模式,基于Servlet技术,抽象出面向组件开发的模型。Tapestry关心的是:页面、组件、事件、对象、方法、属性!

安装jar包

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上。

实例1:最简单的Tapestry程序

在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

实例2:添加简单的动态内容

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

实例3:创建链接,指向某个页面

<!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页面的链接(我们不必关心这个链接!)。

实例4:简单的计数器

直到现在为止,我们还没有涉及到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>

<metakey="org.apache.tapestry.page-class-packages"value="com.bjsxt.crm.web.tapestry.test"/>

</application>

配置的主要目的是让Tapestry了解如何关联页面和页面类。

实例5:带一个参数的计数器

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" parameters="ognl:1">计数器增1</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:doClick" parameters="ognl:5">计数器增5</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:doClick" parameters="ognl:10">计数器增10</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:clearCounter">清空计数器</a>

</body>

</html>

对应的Home类:

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 increment){

int counter = getCounter();

counter = counter + increment;

setCounter(counter);

}

public void clearCounter(){

setCounter(0);

}

}

实例6:带两个参数的计算器

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" parameters="ognl:1">计数器增1</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:doClick" parameters="ognl:5">计数器增5</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:doClick" parameters="ognl:10">计数器增10</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:clearCounter">清空计数器</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:plus" parameters="ognl:{3,5}">计算3+5,</a>

计算结果是:<span jwcid="@Insert" value="ognl:result"></span>

</body>

</html>

使用ognl:{param1,param2}这样的方式来传递多个参数。

对应的Home类:

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 abstract int getResult();

       public abstract void setResult(int result);

public void doClick(int increment){

int counter = getCounter();

counter = counter + increment;

setCounter(counter);

}

public void clearCounter(){

setCounter(0);

}

       public void plus(int a,int b){

              setResult(a + b);

       }

}

实例7:Tapestry表单及提交

假设现在要提交一个Person对象:

package com.bjsxt.crm.web.tapestry.test;

import java.util.Date;

publicclass Person {

//姓名

private String name;

//年龄

privateintage;

//出生日期

private Date birthday;

publicint getAge() {

returnage;

}

publicvoid setAge(int age) {

this.age = age;

}

public Date getBirthday() {

returnbirthday;

}

publicvoid setBirthday(Date birthday) {

this.birthday = birthday;

}

public String getName() {

returnname;

}

publicvoid setName(String name) {

this.name = name;

}

}

我们在Home页面添加一个链接指向添加页面(AddPerson)

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" parameters="ognl:1">计数器增1</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:doClick" parameters="ognl:5">计数器增5</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:doClick" parameters="ognl:10">计数器增10</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:clearCounter">清空计数器</a><br>

<a href="#" jwcid="@DirectLink" listener="listener:plus" parameters="ognl:{3,5}">计算3+5,</a>

计算结果是:<span jwcid="@Insert" value="ognl:result"></span>

<p>

<a href="#" jwcid="@PageLink" page="AddPerson">添加人员信息</a>

</body>

</html>

AddPerson.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html jwcid="@Shell" title="添加人员信息">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=GB18030">

<title>Insert title here</title>

</head>

<body jwcid="@Body">

<form jwcid="@Form" success="listener:save">

<table width="100%"  border="0" cellspacing="1" cellpadding="0">

<tr>

<td width="17%">姓名</td>

<td width="20%"><input type="text" name="textfield" jwcid="@TextField" value="ognl:person.name"/></td>

<td width="10%">年龄</td>

<td width="19%"><input type="text" name="textfield2" jwcid="@TextField" value="ognl:person.age"/></td>

<td width="10%">出生日期</td>

<td width="24%"><input type="text" name="textfield22" jwcid="@DatePicker" translator="translator:date,pattern=yyyy-MM-dd" value="ognl:person.birthday"/></td>

</tr>

<tr>

<td colspan="6"><div align="center">

<input type="submit" name="Submit" value="提交"/>

</div></td>

</tr>

</table>

</form>

</body>

</html>

注意:在页面中的Tapestry组件(使用了jwcid标记)的标签,必须有相应的close tag,特别注意<input/>标签,必须有close tag。

AddPerson.java

package com.bjsxt.crm.web.tapestry.test;

import org.apache.tapestry.event.PageBeginRenderListener;

import org.apache.tapestry.event.PageEvent;

import org.apache.tapestry.html.BasePage;

publicabstractclass AddPerson extends BasePage implements PageBeginRenderListener{

publicabstract Person getPerson();

publicabstractvoid setPerson(Person person);

publicvoid pageBeginRender(PageEvent event) {

setPerson(new Person());

}

publicvoid save(){

Person person = getPerson();

System.out.println("name="+getPerson().getName());

System.out.println("age="+getPerson().getAge());

System.out.println("birthday="+getPerson().getBirthday());

}

}

注意,需定义一个PageBeginRenderListener,来给Person赋予初始化值,否则,OGNL在解释它(Person对象)的属性时,会发生异常!

如何提交中文

我们必须在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.template-encoding" value="GBK"/>

    <meta key="org.apache.tapestry.output-encoding" value="GBK"/>

<metakey="org.apache.tapestry.page-class-packages"value="com.bjsxt.crm.web.tapestry.test"/>

</application>

如何转向其它页面

利用@InjectPage注解直接注入页面。如:

    @InjectPage("ShowProject")
public abstract ShowProject getShowProject(); 
 
  public IPage doSubmit()
  {
    ShowProject showProject = getShowProject();
 
    showProject.setProject(getProject());
 
    return showProject;
  }  

Tapestry概要

在Tapestry中不用写Action,而是listener method。你不用去构建URL地址,而是使用DirectLink组件,并配置它调用listener method。

Tapestry以组件为中心。所谓以组件为中心,即:

l       Tapestry应用程序由一系列页面(page)组成

l       页面由更小的组件(Component)组成

l       组件本身也有可能由其它的组件组合而成的(不限制组合的深度)

l       每个页面会有唯一的,不重复的名字

l       在每个页面里面的组件,其标识也是不能重复的(默认的情况下,Tapestry会给页面中的每个组件自动生成一个ID标识)

Tapestry与Spring的集成

集成需要用到第三方的类库,可以下载: http://howardlewisship.com/downloads/tapestry-javaforge/tapestry-spring-1.0.0-bin.zip

将其解压之后,将其中的jar包拷贝到类路径中。

在我们的页面类中,就可以用@InjectObject(“spring:userManager”)等类似的方法来访问userManager对象了。

如:

@InjectObject("spring:userManager")

public abstract UserManager getUserManager();

Tapestry经典入门教程相关推荐

  1. mysql 经典入门教程_MySQL 经典入门教程

    MySQL 经典入门教程 1 定义 数据库中的表:一行叫一条记录.每一列叫一个属性,或一个字段. 主键:表中的某个特殊字段,具有唯一的确定的值,可以根据该字段唯一的确定一条记录 外键:表中的某个字段的 ...

  2. 传智播客linux安装视频教程下载,传智播客 LAMP(Linux)经典入门教程 李东超主讲29集完整版教程下载...

    课程名称 传智播客 LAMP(Linux)经典入门教程 李东超主讲29集完整版教程下载 课程目录 李东超 PHP视频教程 LAMP经典入门 第01讲 Linux的基本概念和发展历史.wmv 李东超 P ...

  3. 批处理经典入门教程!(从不懂到高手)

    脚本之家补充说明:批处理相对来说是比较简单的语言,大家可以通过多写多看别人的实例来学习,不懂的百度一下. 这是一篇技术教程,真心诚意会用很简单的文字表达清楚自己的意思,只要你识字就能看懂,就能学到知识 ...

  4. 《转》批处理经典入门教程!(从不懂到高手)

    转自: https://www.jb51.net/article/7131_all.htm 这是一篇技术教程,真心诚意会用很简单的文字表达清楚自己的意思,只要你识字就能看懂,就能学到知识.写这篇教程的 ...

  5. 【转载文章】批处理经典入门教程!(从不懂到高手)____附加我的学习笔记

    原文地址https://www.jb51.net/article/7131_all.htm 这篇文章好像是51jb上推荐的比较好入门的一篇了,看了全文确实很有收获 文章推测写与2000-2004年之间 ...

  6. python经典入门教程_Python入门经典(2K超清)

    作者 Toby,持牌照消费金融模型专家,发明金融模型算法专利,和中科院,清华大学,百度,腾讯,爱奇艺,同盾,聚信立,友盟等平台保持长期项目合作:与国内多所财经大学有模型项目.熟悉消费金融场景业务,包括 ...

  7. 批处理经典入门教程!!!

    写这篇教程的目的,是让每一个看过这些文字的朋友记住一句话:如果爱可以让事情变的更简单,那么就让它简单吧!看这篇教程的方法 脚本之家补充说明:批处理相对来说是比较简单的语言,大家可以通过多写多看别人的实 ...

  8. Visual Studio 2010 c++经典入门教程

    系列教程地址:http://www.jizhuomi.com/software/129.html 要源文件和课件的请留言,留下口口邮箱

  9. python正则表达式实例教程_Python正则表达式经典入门教程

    本文实例总结了Python正则表达式基本用法.分享给大家供大家参考,具体如下: 正则表达式在平时做文本处理(爬虫程序去解析html中的字段,在分析log文件的时候需要抓取一些关键数据)的时候经常会用到 ...

最新文章

  1. easyui使用ajax获取json文件,easyui 加载本地json 文件的方法
  2. 大数据WEB工具Hue
  3. opencv多线程显示的问题和解决方法
  4. openkm zip 导入乱码问题解决
  5. 提高关键词排名的28个SEO技巧
  6. java支持多线程吗_Java多线程之一
  7. 小米启动安心服务月 手机家电产品可免费清洁保养
  8. 70进货卖100利润是多少_3个暴利行业,进货价几十块,售卖几百块
  9. 华硕笔记本 X550JD4710HQ
  10. Linux搭建es集群详细教程(最终版)
  11. 利用反射等离激元超表面的模拟光计算
  12. 葡萄柚能放冰箱保存吗 葡萄柚怎么保存时间长
  13. 一天一阔阔儿ZYNQ的linux移植完整版(Linux环境搭建以及内核编译)
  14. 注意:网站中出现以下违规内容-搜索引擎百度都不收录
  15. (软考中级--信息安全工程师)四、网络安全体系与网络安全模型
  16. macos各版本汇总
  17. C++ 数组名a、数组名取地址a、数组首地址a[0]、数组指针*p
  18. 通道结构体_超账结构中系统通道和应用程序通道上的配置更新
  19. K_A13_001 基于STM32驱动霍尔开关传感器 串口与OLED0.96双显示
  20. sns.boxplot()简单用法

热门文章

  1. 英语Catarinite天铁托甲catarinite镍铁陨石
  2. 微光互联 TX800-U 扫码器无法输出中文到光标的问题
  3. 计算图片中矩形间的IOU
  4. CAD修复块中心(com接口c#语言)
  5. 使用MySql计算两个日期的时间差函数:TIMESTAMPDIFF
  6. Codeforces 300D Painting Square 题解
  7. keil问题总结(方便以后查找问题)
  8. 快速识记会计中的借贷两方
  9. 2021-04-19一万小时定律
  10. C++多线程std::async、std::future、std::packaged_task、std::promise