分享
 
 
 

取代JSP的新技术-tapestry

王朝java/jsp·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

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

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有