<%@ page contentType="text/html; charset=gb2312"%> 取代JSP的新技术--tapestry
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
取代JSP的新技术--tapestry
     发布者: 发布时间:2007-10-26

在如今的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。

Application Engine:

当客户连接到Tapestry应用时,Tapestry将会创建一个Engine对象(类似于session)。通常我们程序中的application engine 一般是SimpleEngine类的一个实例,当然这个类的子类也可以。

Page Specification:
跟应用说明相似,页说明也是一个xml描述文件:

因为这个应用是静态的,所以使用com.primix.tapestry.BasePage即可,如果是动态的应用,则需在这个文件中定义一些component,当然使用BasePage为基类的派生类也可以。
html页面:
这个应用的html页面非常简单:

HelloWorld

注意上面所讲到的各种文件都要放到放在WAR的WEB-INF/classes目录下。


一个复杂的应用


在这个应用中我们以一个简单的学生管理系统为例介绍一下Tapestry的常用功能。我们要实现学生的增加和显示,因此我们需要两个html页面。至于StudentServlet类和Student.application我们就不描述了,在Student.application中定义了两个page:Home和EditStudent,具体看附件。学生数据存放在数据库中,我们用Student类表示数据中的一条记录,用StudentFactory类检索学生数据,这两个类用到了一个JDBC包装器,关于这个JDBC包装器可以见我的另外一篇文章<<对一个简单的 JDBC 包装器的扩展及应用>>。
首先看一下Home.html

学生列表

学号
姓名
性别
班级

20012400
宗锋

计算机研一

20011389
桑一珊

计算机研一

添加学生

与前面的简单应用不同,我们在这个页面中定义了七个组件,下面看一下部分Home.jwc文件,我们将详细讲述一下怎样描述这些组件。

EditStudent

在这里,我们的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
学生管理系统
学号:
姓名:
性别:




班级:
在这个文件中,用到了另外一些常用的组件,先看一下EditStudent.jwc中的这些组件的描述:
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文件的片断:


在changeButton组件中就使用了private assets,而这些图像文件就放在WAR的WEB-INF/classes下,注意图像跟html一样也有多个语言的版本。
注意jwc文件中的inputLocale这个组件,其实localization应用就是通过这个组件来实现本地化。具体参数请看其Developer guide。


Tapestry还支持创建自己的可重用组件,其自身带了一个这样的例子:Border。同时它还有其它一些例子:Inspector展示了怎样监视你的应用程序。vlib是一个用tapestry作表示层的j2ee应用程序(用jboss作为应用服务器)。

Tapestry的功能非常强大,本文只是介绍了其一小部分,还有很多方面没有涉及到,例如javascript在Tapestry中的应用。具体可以看其文档,相信如果你用一下这个框架,你就会被它深深吸引。Tapestry的文档做的不是很全,不过经过不断的摸索,相信你会很快掌握它
(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
怎样读取和处理XML的配置文件
在Java程序中实现回调例程
Java Socket编程简捷学习过程
如何动态调用之Java脚本API
对象的序列化和反序列化实践
J2EE基础--步入J2EE架构和过程(1)
 
最近评论:
        
鍥炲
        
那个雨天的想法!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(6448)
        
如果真的有来生!
四川旅游,九寨沟旅游,稻城亚丁旅游,四姑娘山旅游,海螺沟旅游,西藏旅游, max(4888)
        
那天的情景!
Maple Story mesos,MapleStory mesos,ms mesos,mesos,SilkRoad Gold, max(459)
        
如果真的有来生!
四川旅游,九寨沟旅游,稻城亚丁旅游,四姑娘山旅游,海螺沟旅游,西藏旅游, max(4066)
        
如果真的有来生!
四川旅游,九寨沟旅游,稻城亚丁旅游,四姑娘山旅游,海螺沟旅游,西藏旅游, max(1556)
        
轻轻走过你的窗前!
world of warcraft gold,cheap world of warcraft gold,warcraft gold,world of warcraft gold,cheap world of warcraft gold,warcraft gold, max(8553)
        
轻轻走过你的窗前!
world of warcraft gold,cheap world of warcraft gold,warcraft gold,world of warcraft gold,cheap world of warcraft gold,warcraft gold max(9151)
        
快乐情人节!
wow gold,wow gold,wow gold,wow gold,wow gold,wow gold,wow gold buy wow gold for cheap. max(1450)
        
没有情人的情人节!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(8697)
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号