- 浏览: 58813 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
liumingtong:
我想要你的联系方式.可以吗?要不你加我Q 3813774
success -
抛出异常的爱:
congdepeng 写道Liskov替换原则(LSP)
描 ...
设计原则 -
wumingshi:
楼主关于LSP的解释是错误的。LSP的精髓是,使用父类的代码可 ...
设计原则 -
liumingtong:
struts2的OGNL表达式
struts2的值栈
st ...
总结struts2 完成中······ -
Cindy_Lee:
Joy.zhang 写道
下面是具体的设计模式:
单例 ...
设计模式中11种
Tapestry 的功能非常强大,本文只是介绍了其一小部分,还有很多方面没有涉及到,例如javascript在Tapestry中的应用。具体可以看其文档,相信如果你用一下这个框架,你就会被它深深吸引。Tapestry的文档做的不是很全,不过经过不断的摸索,相信你会很快掌握它。
在如今的web开发中,基于java的应用越来越多。在这其中,servlet又扮演着十分重要的角色。本系列文章就是要介绍一些辅助进行servlet开发的工具,让大家进行开发时,有多种技术可供选择。
servlet 技术无疑是一种优秀的技术,java服务器端技术大都基于servlet技术。但这种技术也有其自身的不足,例如:表示层(html代码)与代码混在一起,可重用性不高。SUN于是提出了jsp技术,jsp也是基于servlet的一种技术,使用它你可以在html中嵌入java代码。jsp在 servlet的基础上迈进了一大步,但单纯的jsp也有上面提到的servlet的缺点。不过利用jsp+javabean+taglib这种开发模式可以解决上面提到的缺点。但jsp本身还有其它一些不足,具体参看The Problems with JSP这篇文章。于是人们便开发了其它一些基于servlet的技术。我们首先介绍一下Tapestry。
简介
Tapestry 是一个开源的基于servlet的应用程序框架,它使用组件对象模型来创建动态的,交互的web应用。一个组件就是任意一个带有jwcid属性的html 标记。其中jwc的意思是Java Web Component。Tapestry使得java代码与html完全分离,利用这个框架开发大型应用变得轻而易举。并且开发的应用很容易维护和升级。 Tapestry支持本地化,其错误报告也很详细。Tapestry主要利用javabean和xml技术进行开发。
第一个应用程序
在介绍第一个应用之前,先介绍一下Tapestry的安装。从sourceforge下载其最新版,解压后,将 lib目录下的jar文件放到 CLASSPATH中,将其中的war文件放到tomcat的webapp目录下。然后就可以通过http://localhost: 8080/tutorial访问其tutorial应用。
在Tapestry中一个应用程序有以下几部分组成,我们以其自身带的HelloWorld程序为例介绍:
Servlet:
这是一个应用的主体部分:servlet类,这个类必须是ApplicationServlet的子类,并且必须实现 getApplicationSpecificationPath()方法。示例如下:
import com.primix.tapestry.*;
public class HelloWorldServlet extends ApplicationServlet
{
protected String getApplicationSpecificationPath()
{
return "/tutorial/hello/HelloWorld.application";
}
}
/tutorial/hello/HelloWorld.application是一个应用的说明文件。
Application Specification:
其实就是描述这个应用的一个xml文件,在这个应用中有许多参数需要设置,engine-class将在下面介绍,page中的name属性指定html 文件名,specification-path指定对这个页面的说明文件。在一个应用中可以有很多个page,但必须有一个page的name为 "Home",因为当访问你的应用时,首先显示的就是这个page。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Howard Ship//Tapestry Specification 1.1//EN" "http://tapestry.sf.net/dtd/Tapestry_1_1.dtd">
<application name="Hello World Tutorial" engine-class="com.primix.tapestry.engine.SimpleEngine">
<page name="Home" specification-path="/tutorial/hello/Home.jwc"/>
</application>
Application Engine:
当客户连接到Tapestry应用时,Tapestry将会创建一个Engine对象(类似于session)。通常我们程序中的application engine 一般是SimpleEngine类的一个实例,当然这个类的子类也可以。
Page Specification:
跟应用说明相似,页说明也是一个xml描述文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE specification PUBLIC "-//Howard Ship//Tapestry Specification 1.1//EN" "http://tapestry.sf.net/dtd/Tapestry_1_1.dtd">
<specification class="com.primix.tapestry.BasePage"/>
因为这个应用是静态的,所以使用com.primix.tapestry.BasePage即可,如果是动态的应用,则需在这个文件中定义一些 component,当然使用BasePage为基类的派生类也可以。
html页面:
这个应用的html页面非常简单:
<html>
<head>
<title>Hello World</title>
</head>
<body>
<b>HelloWorld</b>
</body>
</html>
注意上面所讲到的各种文件都要放到放在WAR的WEB-INF/classes目录下。
一个复杂的应用
在这个应用中我们以一个简单的学生管理系统为例介绍一下Tapestry的常用功能。我们要实现学生的增加和显示,因此我们需要两个html页面。至于 StudentServlet类和Student.application我们就不描述了,在Student.application中定义了两个 page:Home和EditStudent,具体看附件。学生数据存放在数据库中,我们用Student类表示数据中的一条记录,用 StudentFactory类检索学生数据,这两个类用到了一个JDBC包装器,关于这个JDBC包装器可以见我的另外一篇文章<<对一个简单的 JDBC 包装器的扩展及应用>>。
首先看一下Home.html
<html>
<head>
<title>学生管理</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF">
<p align="center">学生列表</p>
<table width="100%" border="1">
<tr>
<td >学号</td>
<td >姓名</td>
<td >性别</td>
<td >班级</td>
</tr>
<span jwcid="liststudent">
<tr>
<td><span jwcid="id">20012400</span></td>
<td><span jwcid="sname">宗锋</span></td>
<td><span jwcid="gender">男</span></td>
<td><span jwcid="department">计算机研一</span></td>
</tr>
</span>
<tr jwcid="$remove$">
<td>20011389</td>
<td>桑一珊</td>
<td>男</td>
<td>计算机研一</td>
</tr>
</table>
<a jwcid="add">添加学生</a>
</body>
</html>
与前面的简单应用不同,我们在这个页面中定义了七个组件,下面看一下部分Home.jwc文件,我们将详细讲述一下怎样描述这些组件。
<specification class="test.ListStudent">
<component id="liststudent" type="Foreach">
<binding name="source" property-path="student"/>
<binding name="value" property-path="eachstudent"/>
</component>
<component id="id" type="Insert">
<binding name="value" property-path="eachstudent.id"/>
</component>
<component id="add" type="Page">
<static-binding name="page">EditStudent</static-binding>
</component>
</specification>
在这里,我们的specification的class属性值不再是BasePage,而是其派生类 ListStudent。对于每一个组件,id属性指定唯一的标识符,这个值与html文件中的jwcid值相对应,type 指定组件名,binding指定组件怎得到数据,property-path是一系列属性的集合,这些属性一般定义在javabean中,例如上面的 property-path="student",则在相应的javabean类ListStudent中应该有个函数getStudent。 liststudent是一个Foreach组件,这个组件其实是一个for循环,它从source中读入一个数组,将其一个一个的赋值给value参数指定的属性。id,name,gender,department四个是Insert组件,这个组件用来插入文本数据,参数value指定要插入的值, property-path指定怎样获取这些值,eachstudent.id相当于调用javabean的getEachstudent(). getId()。add是一个Page组件,page属性指定页面名(定义在application文件中),static-binding表明要绑定的数据是不可修改的。$remove$组件没有在这个文件中描述,因为Tapestry运行时会自动删除这种组件。
下面看一下ListStudent类:
package test;
import com.primix.tapestry.*;
import sun.jdbc.odbc.JdbcOdbcDriver ;
/**
* 返回每个学生的数据
*
*/
public class ListStudent extends BasePage
{
private Student eachstudent;
private Student[] student;
public void detach()
{
eachstudent=null;
student=null;
super.detach();
}
public Student getEachstudent()
{
return eachstudent;
}
public void setEachstudent(Student value)
{
eachstudent = value;
}
public Student[] getStudent()
{
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
student=StudentFactory.findAllStudents();
}catch(Exception e){
e.printStackTrace();
}
return student;
}
}
这个类有四个函数,其中detach函数是将页面放入缓冲池时执行的操作,getStudent函数返回所有的学生记录,这是给jwc文件中 liststudent组件的source参数赋值,getEachstudent给这个组件的value参数赋值,因为source是一个数组,每次循环需要从中取出一条记录赋值给eachstudent,所以还有一个函数为setEachstudent,你会注意到这个函数很简单,其实是 Tapestry帮你做了大部分工作。
至此,显示学生的部分已经完成,下面看一下EditStudent.html
<html>
<head>
<title>增加学生</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<p><img src="student.gif" width="32" height="32"/> 学生管理系统</p>
<form jwcid="form">
<span jwcid="ifError">
<font size=+2 color=red><span jwcid="insertError"/></font>
</span>
<p>学号:
<input jwcid="id"/>
</p>
<p>姓名:
<input jwcid="name"/>
</p>
<span jwcid="gender">
<p>性别:
<input jwcid="male"/>
男
<input jwcid="female"/>
女
</p>
</span>
<p>班级:
<input jwcid="department"/>
</p>
<p>
<input type="submit" value="确定">
</p>
</form>
</body>
</html>
在这个文件中,用到了另外一些常用的组件,先看一下EditStudent.jwc中的这些组件的描述:
<specification class="test.EditStudent">
<component id="form" type="Form">
<binding name="listener" property-path="listeners.formSubmit"/>
</component>
<component id="gender" type="RadioGroup">
<binding name="selected" property-path="gender"/>
</component>
<component id="ifError" type="Conditional">
<binding name="condition" property-path="error"/>
</component>
<component id="insertError" type="Insert">
<binding name="value" property-path="error"/>
</component>
<component id="id" type="TextField">
<binding name="value" property-path="id"/>
</component>
<component id="male" type="Radio">
<field-binding name="value" field-name="test.EditStudent.MALE"/>
</component>
</specification>
form 是一个Form组件,它的参数listener指定submit这个form时有那个函数处理。ifError是一个Conditional组件,这个组件指定当condition满足时才会显示,在本例中,如果error不为空,则condition满足。在这个组件中,有嵌套了一个Insert类型的组件,用于将错误显示。这是Tapestry中经常用到的处理错误的方式。gender是一个RadioGroup组件,它绑定了javabean中的 gender属性,selected参数指定那个radio被选中,在这个组件中,又嵌套了两个Radio组件,分别用来表示男,女。Radio的 value参数指定当用户选定这个radio时,RadioGroup绑定的属性值将会等于field-name中指定的值(这个值必须是static 的),在本例中,gender=test.EditStudent.MALE。id是一个TextField组件,其参数value绑定到 javabean中的id属性。
下面是相应的EditStudent类:
package test;
import com.primix.tapestry.*;
public class EditStudent extends BasePage
{
public static final int MALE = 1;
public static final int FEMALE = 2;
private int gender;
private String error;
private String id;
private String sname;
private String department;
public void detach()
{
error = null;
id=null;
sname=null;
gender=0;
department=null;
super.detach();
}
public int getGender()
{
return gender;
}
public String getId()
{
return id;
}
public String getSname()
{
return sname;
}
public String getDepartment()
{
return department;
}
public void setGender(int value)
{
gender = value;
fireObservedChange("gender", value);
}
public void setId(String value)
{
id = value;
fireObservedChange("id", value);
}
public String getError()
{
return error;
}
public void setSname(String value)
{
sname = value;
fireObservedChange("sname", value);
}
public void setDepartment(String value)
{
department = value;
fireObservedChange("department", value);
}
public void formSubmit(IRequestCycle cycle)
{
//判断用户是否添完了所有数据
if (gender== 0||id==null||id.equals("")||sname==null||sname.equals("")||
department==null||department.equals(""))
{
error = "请填充完所有选项";
return;
}
//将学生保存
try{
Student student=new Student();
student.setId(id);
student.setName(sname);
if(gender==1)
student.setGender("男");
else
student.setGender("女");
student.setDepartment(department);
student.save(null);
}catch(Exception e){
e.printStackTrace();
}
//清空当前的各个属性,以免再次进入此页面时,各属性仍旧保留原来的值
setSname(null);
setDepartment(null);
setId(null);
setGender(0);
//重定向到Home页面
cycle.setPage("Home");
}
}
在本类的一些设置属性的函数中使用了fireObservedChange这个函数,这个函数激发一个改变事件,通知当前的属性的值已经改变。
其他应用
Tapestry 中自带的例子中的Workbench中的localization例子演示了怎样使用本地化,你只需要创建不同语言的html模板,还有图形等其它一些 html中用到的资源。例如创建一个法语版的EditStudent.html,则相应的html文件名为EditStudent_fr.html,而 jwc中定义的组件的描述不用有多个版本。这里要介绍一下Tapestry本地化中经常用到的一个概念:assets。assets是一些web应用中用到的资源,如图象,视频。assets有三种:external, internal 和private。External类型的assets来源于任意的URL。Internal类型的assets来源于和Tapestry应用在同一个服务器上的URL。Private 类型的assets允许部署在WAR的WEB-INF/classes目录下(同上面的html模板,jwc文件一样),这个目录对于web服务器来说是不可见的。
看一下Workbench中localization例子中的localization.jwc文件的片断:
<component id="changeButton" type="ImageSubmit">
<binding name="image" property-path="assets.change-button"/>
</component>
<private-asset name="change-button" resource-path="/tutorial/workbench/localization/Change.gif"/>
在changeButton组件中就使用了private assets,而这些图像文件就放在WAR的WEB-INF/classes下,注意图像跟html一样也有多个语言的版本。
注意jwc文件中的inputLocale这个组件,其实localization应用就是通过这个组件来实现本地化。具体参数请看其Developer guide。
<component id="inputLocale" type="PropertySelection">
<binding name="value" property-path="page.engine.locale"/>
<binding name="model" property-path="localeModel"/>
</component>
Tapestry还支持创建自己的可重用组件,其自身带了一个这样的例子:Border。同时它还有其它一些例子:Inspector展示了怎样监视你的应用程序。vlib是一个用tapestry作表示层的j2ee应用程序(用jboss作为应用服务器)。
Tapestry 的功能非常强大,本文只是介绍了其一小部分,还有很多方面没有涉及到,例如javascript在Tapestry中的应用。具体可以看其文档,相信如果你用一下这个框架,你就会被它深深吸引。Tapestry的文档做的不是很全,不过经过不断的摸索,相信你会很快掌握它。
在如今的web开发中,基于java的应用越来越多。在这其中,servlet又扮演着十分重要的角色。本系列文章就是要介绍一些辅助进行servlet开发的工具,让大家进行开发时,有多种技术可供选择。
servlet 技术无疑是一种优秀的技术,java服务器端技术大都基于servlet技术。但这种技术也有其自身的不足,例如:表示层(html代码)与代码混在一起,可重用性不高。SUN于是提出了jsp技术,jsp也是基于servlet的一种技术,使用它你可以在html中嵌入java代码。jsp在 servlet的基础上迈进了一大步,但单纯的jsp也有上面提到的servlet的缺点。不过利用jsp+javabean+taglib这种开发模式可以解决上面提到的缺点。但jsp本身还有其它一些不足,具体参看The Problems with JSP这篇文章。于是人们便开发了其它一些基于servlet的技术。我们首先介绍一下Tapestry。
简介
Tapestry 是一个开源的基于servlet的应用程序框架,它使用组件对象模型来创建动态的,交互的web应用。一个组件就是任意一个带有jwcid属性的html 标记。其中jwc的意思是Java Web Component。Tapestry使得java代码与html完全分离,利用这个框架开发大型应用变得轻而易举。并且开发的应用很容易维护和升级。 Tapestry支持本地化,其错误报告也很详细。Tapestry主要利用javabean和xml技术进行开发。
第一个应用程序
在介绍第一个应用之前,先介绍一下Tapestry的安装。从sourceforge下载其最新版,解压后,将 lib目录下的jar文件放到 CLASSPATH中,将其中的war文件放到tomcat的webapp目录下。然后就可以通过http://localhost: 8080/tutorial访问其tutorial应用。
在Tapestry中一个应用程序有以下几部分组成,我们以其自身带的HelloWorld程序为例介绍:
Servlet:
这是一个应用的主体部分:servlet类,这个类必须是ApplicationServlet的子类,并且必须实现 getApplicationSpecificationPath()方法。示例如下:
import com.primix.tapestry.*;
public class HelloWorldServlet extends ApplicationServlet
{
protected String getApplicationSpecificationPath()
{
return "/tutorial/hello/HelloWorld.application";
}
}
/tutorial/hello/HelloWorld.application是一个应用的说明文件。
Application Specification:
其实就是描述这个应用的一个xml文件,在这个应用中有许多参数需要设置,engine-class将在下面介绍,page中的name属性指定html 文件名,specification-path指定对这个页面的说明文件。在一个应用中可以有很多个page,但必须有一个page的name为 "Home",因为当访问你的应用时,首先显示的就是这个page。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Howard Ship//Tapestry Specification 1.1//EN" "http://tapestry.sf.net/dtd/Tapestry_1_1.dtd">
<application name="Hello World Tutorial" engine-class="com.primix.tapestry.engine.SimpleEngine">
<page name="Home" specification-path="/tutorial/hello/Home.jwc"/>
</application>
Application Engine:
当客户连接到Tapestry应用时,Tapestry将会创建一个Engine对象(类似于session)。通常我们程序中的application engine 一般是SimpleEngine类的一个实例,当然这个类的子类也可以。
Page Specification:
跟应用说明相似,页说明也是一个xml描述文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE specification PUBLIC "-//Howard Ship//Tapestry Specification 1.1//EN" "http://tapestry.sf.net/dtd/Tapestry_1_1.dtd">
<specification class="com.primix.tapestry.BasePage"/>
因为这个应用是静态的,所以使用com.primix.tapestry.BasePage即可,如果是动态的应用,则需在这个文件中定义一些 component,当然使用BasePage为基类的派生类也可以。
html页面:
这个应用的html页面非常简单:
<html>
<head>
<title>Hello World</title>
</head>
<body>
<b>HelloWorld</b>
</body>
</html>
注意上面所讲到的各种文件都要放到放在WAR的WEB-INF/classes目录下。
一个复杂的应用
在这个应用中我们以一个简单的学生管理系统为例介绍一下Tapestry的常用功能。我们要实现学生的增加和显示,因此我们需要两个html页面。至于 StudentServlet类和Student.application我们就不描述了,在Student.application中定义了两个 page:Home和EditStudent,具体看附件。学生数据存放在数据库中,我们用Student类表示数据中的一条记录,用 StudentFactory类检索学生数据,这两个类用到了一个JDBC包装器,关于这个JDBC包装器可以见我的另外一篇文章<<对一个简单的 JDBC 包装器的扩展及应用>>。
首先看一下Home.html
<html>
<head>
<title>学生管理</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF">
<p align="center">学生列表</p>
<table width="100%" border="1">
<tr>
<td >学号</td>
<td >姓名</td>
<td >性别</td>
<td >班级</td>
</tr>
<span jwcid="liststudent">
<tr>
<td><span jwcid="id">20012400</span></td>
<td><span jwcid="sname">宗锋</span></td>
<td><span jwcid="gender">男</span></td>
<td><span jwcid="department">计算机研一</span></td>
</tr>
</span>
<tr jwcid="$remove$">
<td>20011389</td>
<td>桑一珊</td>
<td>男</td>
<td>计算机研一</td>
</tr>
</table>
<a jwcid="add">添加学生</a>
</body>
</html>
与前面的简单应用不同,我们在这个页面中定义了七个组件,下面看一下部分Home.jwc文件,我们将详细讲述一下怎样描述这些组件。
<specification class="test.ListStudent">
<component id="liststudent" type="Foreach">
<binding name="source" property-path="student"/>
<binding name="value" property-path="eachstudent"/>
</component>
<component id="id" type="Insert">
<binding name="value" property-path="eachstudent.id"/>
</component>
<component id="add" type="Page">
<static-binding name="page">EditStudent</static-binding>
</component>
</specification>
在这里,我们的specification的class属性值不再是BasePage,而是其派生类 ListStudent。对于每一个组件,id属性指定唯一的标识符,这个值与html文件中的jwcid值相对应,type 指定组件名,binding指定组件怎得到数据,property-path是一系列属性的集合,这些属性一般定义在javabean中,例如上面的 property-path="student",则在相应的javabean类ListStudent中应该有个函数getStudent。 liststudent是一个Foreach组件,这个组件其实是一个for循环,它从source中读入一个数组,将其一个一个的赋值给value参数指定的属性。id,name,gender,department四个是Insert组件,这个组件用来插入文本数据,参数value指定要插入的值, property-path指定怎样获取这些值,eachstudent.id相当于调用javabean的getEachstudent(). getId()。add是一个Page组件,page属性指定页面名(定义在application文件中),static-binding表明要绑定的数据是不可修改的。$remove$组件没有在这个文件中描述,因为Tapestry运行时会自动删除这种组件。
下面看一下ListStudent类:
package test;
import com.primix.tapestry.*;
import sun.jdbc.odbc.JdbcOdbcDriver ;
/**
* 返回每个学生的数据
*
*/
public class ListStudent extends BasePage
{
private Student eachstudent;
private Student[] student;
public void detach()
{
eachstudent=null;
student=null;
super.detach();
}
public Student getEachstudent()
{
return eachstudent;
}
public void setEachstudent(Student value)
{
eachstudent = value;
}
public Student[] getStudent()
{
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
student=StudentFactory.findAllStudents();
}catch(Exception e){
e.printStackTrace();
}
return student;
}
}
这个类有四个函数,其中detach函数是将页面放入缓冲池时执行的操作,getStudent函数返回所有的学生记录,这是给jwc文件中 liststudent组件的source参数赋值,getEachstudent给这个组件的value参数赋值,因为source是一个数组,每次循环需要从中取出一条记录赋值给eachstudent,所以还有一个函数为setEachstudent,你会注意到这个函数很简单,其实是 Tapestry帮你做了大部分工作。
至此,显示学生的部分已经完成,下面看一下EditStudent.html
<html>
<head>
<title>增加学生</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<p><img src="student.gif" width="32" height="32"/> 学生管理系统</p>
<form jwcid="form">
<span jwcid="ifError">
<font size=+2 color=red><span jwcid="insertError"/></font>
</span>
<p>学号:
<input jwcid="id"/>
</p>
<p>姓名:
<input jwcid="name"/>
</p>
<span jwcid="gender">
<p>性别:
<input jwcid="male"/>
男
<input jwcid="female"/>
女
</p>
</span>
<p>班级:
<input jwcid="department"/>
</p>
<p>
<input type="submit" value="确定">
</p>
</form>
</body>
</html>
在这个文件中,用到了另外一些常用的组件,先看一下EditStudent.jwc中的这些组件的描述:
<specification class="test.EditStudent">
<component id="form" type="Form">
<binding name="listener" property-path="listeners.formSubmit"/>
</component>
<component id="gender" type="RadioGroup">
<binding name="selected" property-path="gender"/>
</component>
<component id="ifError" type="Conditional">
<binding name="condition" property-path="error"/>
</component>
<component id="insertError" type="Insert">
<binding name="value" property-path="error"/>
</component>
<component id="id" type="TextField">
<binding name="value" property-path="id"/>
</component>
<component id="male" type="Radio">
<field-binding name="value" field-name="test.EditStudent.MALE"/>
</component>
</specification>
form 是一个Form组件,它的参数listener指定submit这个form时有那个函数处理。ifError是一个Conditional组件,这个组件指定当condition满足时才会显示,在本例中,如果error不为空,则condition满足。在这个组件中,有嵌套了一个Insert类型的组件,用于将错误显示。这是Tapestry中经常用到的处理错误的方式。gender是一个RadioGroup组件,它绑定了javabean中的 gender属性,selected参数指定那个radio被选中,在这个组件中,又嵌套了两个Radio组件,分别用来表示男,女。Radio的 value参数指定当用户选定这个radio时,RadioGroup绑定的属性值将会等于field-name中指定的值(这个值必须是static 的),在本例中,gender=test.EditStudent.MALE。id是一个TextField组件,其参数value绑定到 javabean中的id属性。
下面是相应的EditStudent类:
package test;
import com.primix.tapestry.*;
public class EditStudent extends BasePage
{
public static final int MALE = 1;
public static final int FEMALE = 2;
private int gender;
private String error;
private String id;
private String sname;
private String department;
public void detach()
{
error = null;
id=null;
sname=null;
gender=0;
department=null;
super.detach();
}
public int getGender()
{
return gender;
}
public String getId()
{
return id;
}
public String getSname()
{
return sname;
}
public String getDepartment()
{
return department;
}
public void setGender(int value)
{
gender = value;
fireObservedChange("gender", value);
}
public void setId(String value)
{
id = value;
fireObservedChange("id", value);
}
public String getError()
{
return error;
}
public void setSname(String value)
{
sname = value;
fireObservedChange("sname", value);
}
public void setDepartment(String value)
{
department = value;
fireObservedChange("department", value);
}
public void formSubmit(IRequestCycle cycle)
{
//判断用户是否添完了所有数据
if (gender== 0||id==null||id.equals("")||sname==null||sname.equals("")||
department==null||department.equals(""))
{
error = "请填充完所有选项";
return;
}
//将学生保存
try{
Student student=new Student();
student.setId(id);
student.setName(sname);
if(gender==1)
student.setGender("男");
else
student.setGender("女");
student.setDepartment(department);
student.save(null);
}catch(Exception e){
e.printStackTrace();
}
//清空当前的各个属性,以免再次进入此页面时,各属性仍旧保留原来的值
setSname(null);
setDepartment(null);
setId(null);
setGender(0);
//重定向到Home页面
cycle.setPage("Home");
}
}
在本类的一些设置属性的函数中使用了fireObservedChange这个函数,这个函数激发一个改变事件,通知当前的属性的值已经改变。
其他应用
Tapestry 中自带的例子中的Workbench中的localization例子演示了怎样使用本地化,你只需要创建不同语言的html模板,还有图形等其它一些 html中用到的资源。例如创建一个法语版的EditStudent.html,则相应的html文件名为EditStudent_fr.html,而 jwc中定义的组件的描述不用有多个版本。这里要介绍一下Tapestry本地化中经常用到的一个概念:assets。assets是一些web应用中用到的资源,如图象,视频。assets有三种:external, internal 和private。External类型的assets来源于任意的URL。Internal类型的assets来源于和Tapestry应用在同一个服务器上的URL。Private 类型的assets允许部署在WAR的WEB-INF/classes目录下(同上面的html模板,jwc文件一样),这个目录对于web服务器来说是不可见的。
看一下Workbench中localization例子中的localization.jwc文件的片断:
<component id="changeButton" type="ImageSubmit">
<binding name="image" property-path="assets.change-button"/>
</component>
<private-asset name="change-button" resource-path="/tutorial/workbench/localization/Change.gif"/>
在changeButton组件中就使用了private assets,而这些图像文件就放在WAR的WEB-INF/classes下,注意图像跟html一样也有多个语言的版本。
注意jwc文件中的inputLocale这个组件,其实localization应用就是通过这个组件来实现本地化。具体参数请看其Developer guide。
<component id="inputLocale" type="PropertySelection">
<binding name="value" property-path="page.engine.locale"/>
<binding name="model" property-path="localeModel"/>
</component>
Tapestry还支持创建自己的可重用组件,其自身带了一个这样的例子:Border。同时它还有其它一些例子:Inspector展示了怎样监视你的应用程序。vlib是一个用tapestry作表示层的j2ee应用程序(用jboss作为应用服务器)。
Tapestry 的功能非常强大,本文只是介绍了其一小部分,还有很多方面没有涉及到,例如javascript在Tapestry中的应用。具体可以看其文档,相信如果你用一下这个框架,你就会被它深深吸引。Tapestry的文档做的不是很全,不过经过不断的摸索,相信你会很快掌握它。
发表评论
-
利用jsp读取远程文件保存到本地
2010-07-14 18:02 1838本文介绍利用jsp读取远程文件保存到本地的文章专题。 用js ... -
jsp+tomcat+mysql&sevlet&javabean配置
2010-07-14 18:01 677在配置jsp开发环境的过 ... -
JSP中用bean封装常用的功能
2010-07-14 18:00 710本文介绍JSP中用bean封装常用的功能的文章专题。 1、建 ... -
JSP中关于html的转换技巧
2010-07-14 17:59 609本文介绍JSP中关于html的转换技巧的文章专题。 publ ... -
在JSP中设置HTTP应答头
2010-07-14 17:58 766本文介绍在JSP中设置HTTP应答头的文章专题。 Prime ... -
在JSP中访问CORBA服务对象实例
2010-07-14 17:58 801结合J2EE和CORBA可以充分 ... -
学习jsp与javascript结合在页面间传递参数
2010-07-14 17:57 1282本文介绍学习jsp与javascript结合在页面间传递参数的 ... -
JSP Commons FileUpload 组件上传文件的总结
2010-07-14 17:57 907本文介绍JSP Commons FileUpload 组件上传 ... -
JSP开发前设置
2010-07-14 17:56 681由于朋友问起我开发JSP前都要做些什么,就写了这篇东东。 ? ... -
JSP应用语法详解集三
2010-07-14 17:56 730本文介绍JSP应用语法详 ... -
JSP应用语法详解集二
2010-07-14 17:55 676本文介绍JSP应用语法详解集二的文章专题。 8)标签: 转发 ... -
JSP应用语法详解集一
2010-07-14 17:55 597本文介绍JSP应用语法详解:HTML注释,隐藏注释,Page指 ... -
提升JSP应用程序的7大绝招
2010-07-14 17:54 728本文的目的是通过对servlet和JSP的一些调优技术来极大地 ... -
JSP技巧之:session在何时被创建
2010-07-14 17:54 642本文介绍JSP技巧之:session在何时被创建的文章专题。 ... -
谈谈JSP的九个隐含对象
2010-07-14 17:53 875本文介绍谈谈JSP的九个隐含对象的文章专题,例如:储存和取得属 ... -
解决JSP与MySQL交互的中文乱码问题
2010-07-14 17:51 668首先实现了一个StringConvert bean(GBtoI ... -
JSP几个常见问题
2010-07-14 17:51 696本文介绍JSP几个常见问题的文章专题,Hashtable和 H ... -
JSp的Taglib Directiv语法,属性概述
2010-07-14 17:50 747指示(directive)允许您使用自定义的标签,为标签库命名 ... -
JSP连接SQL Server 2000系统详细配置
2010-07-14 17:50 592到SUN官方站点(http://java.sun.com)下载 ... -
JSP中标签库的深入研究
2010-07-14 17:50 634标签处理器和标签附加信息需要定位在JSP容器类载入器可以找到的 ...
相关推荐
Tapestry5最新中文教程.doc 作者 Renat Zubairov & Igor Drobiazko译者 沙晓兰 发布于 2008年7月2日 下午9时30分 社区 Java 主题 Web框架 ----------------------------------------- Tapestry5.1实例教程.pdf ...
包含的`apache-tapestry-5.3.7-javadocs.zip`文件提供了完整的API文档,对于开发者来说,这是一个宝贵的资源,可以帮助理解框架的各个部分以及如何使用它们。`apache-tapestry-5.3.7-sources.zip`则包含了源代码,...
gaedo-tapestry-0.4.6.jar
gaedo-tapestry-0.4.9.jar
gaedo-tapestry-0.4.5.jar
gaedo-tapestry-0.4.4.jar
gaedo-tapestry-0.4.3.jar
gaedo-tapestry-0.4.15.jar
gaedo-tapestry-0.4.8.jar
`apache-tapestry-5.3.8-bin.zip` 是Apache Tapestry 5.3.8版本的二进制发行包,包含了运行和开发Tapestry应用所需的各种库文件。 1. **Tapestry框架**:Tapestry是由Howard Lewis Ship创建的一个MVC(Model-View-...
chenillekit-tapestry-1.3.2.jar
与传统的基于Servlet或JSP的Web开发相比,Tapestry采用了一种更高级别的抽象,使得开发者可以更加关注业务逻辑而非底层的HTTP细节。本书首先介绍了Tapestry的基本概念,包括其组件模型、请求处理流程以及与MVC设计...
`tapestry-jpa-5.3.7.jar`和`tapestry-hibernate-5.3.7.jar`则与持久层集成有关,它们支持JPA(Java Persistence API)和Hibernate ORM框架,使开发者能够轻松地在Tapestry应用中处理数据库操作。 总的来说,Apache...
实测可用
实测可用
实测可用
实测可用
实测可用