取代JSP的新技术--tapestry!!! 

779 篇文章 0 订阅
<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

  在如今的web开发中,基于java的应用越来越多。在这其中,servlet又扮演着十分重要的角色。本系列文章就是要介绍一些辅助进行servlet开发的工具,让大家进行开发时,有多种技术可供选择。

  servlet技术无疑是一种优秀的技术,java服务器端技术大都基于servlet技术。但这种技术也有其自身的不足,例如:表示层(html代码)与代码混在一起,可重用性不高。SUN于是提出了JSP技术,JSP也是基于servlet的一种技术,使用它你可以在html中嵌入java代码。JSP在servlet的基础上迈进了一大步,但单纯的JSP也有上面提到的servlet的缺点。不过利用JSP+javabean+taglib这种开发模式可以解决上面提到的缺点。但JSP本身还有其它一些不足,具体参看TheProblemswithJSP这篇文章。于是人们便开发了其它一些基于servlet的技术。我们首先介绍一下tapestry

  简介

  tapestry是一个开源的基于servlet的应用程序框架,它使用组件对象模型来创建动态的,交互的web应用。一个组件就是任意一个带有jwcid属性的html标记。其中jwc的意思是JavaWebComponent。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()方法。示例如下:

  importcom.primix.tapestry.*;

  publicclassHelloWorldServletextendsApplicationServlet

  {

  protectedStringgetApplicationSpecificationPath()

  {

  return"/tutorial/hello/HelloWorld.application";

  }

  }

  /tutorial/hello/HelloWorld.application是一个应用的说明文件。

  ApplicationSpecification:

  其实就是描述这个应用的一个xml文件,在这个应用中有许多参数需要设置,engine-class将在下面介绍,page中的name属性指定html文件名,specification-path指定对这个页面的说明文件。在一个应用中可以有很多个page,但必须有一个page的name为"Home",因为当访问你的应用时,首先显示的就是这个page。

 

  tapestrySpecification1.1//EN""http://tapestry.sf.net/dtd/tapestry_1_1.dtd">

  tapestry.engine.SimpleEngine">

 

 

  ApplicationEngine:

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

  PageSpecification:

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

 

  tapestrySpecification1.1//EN""http://tapestry.sf.net/dtd/tapestry_1_1.dtd">

  tapestry.BasePage"/>

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

  html页面:

  这个应用的html页面非常简单:

 

 

  HelloWorld

 

 

  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类:

  packagetest;

  importcom.primix.tapestry.*;

  importsun.jdbc.odbc.JdbcOdbcDriver;

  /**

  *返回每个学生的数据

  *

  */

  publicclassListStudentextendsBasePage

  {

  privateStudenteachstudent;

  privateStudent[]student;

  publicvoiddetach()

  {

  eachstudent=null;

  student=null;

  super.detach();

  }

  publicStudentgetEachstudent()

  {

  returneachstudent;

  }

  publicvoidsetEachstudent(Studentvalue)

  {

  eachstudent=value;

  }

  publicStudent[]getStudent()

  {

  try{

  Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

  student=StudentFactory.findAllStudents();

  }catch(Exceptione){

  e.printStackTrace();

  }

  returnstudent;

  }

  }

  这个类有四个函数,其中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类:

  packagetest;

  importcom.primix.tapestry.*;

  publicclassEditStudentextendsBasePage

  {

  publicstaticfinalintMALE=1;

  publicstaticfinalintFEMALE=2;

  privateintgender;

  privateStringerror;

  privateStringid;

  privateStringsname;

  privateStringdepartment;

  publicvoiddetach()

  {

  error=null;

  id=null;

  sname=null;

  gender=0;

  department=null;

  super.detach();

  }

  publicintgetGender()

  {

  returngender;

  }

  publicStringgetId()

  {

  returnid;

  }

  publicStringgetSname()

  {

  returnsname;

  }

  publicStringgetDepartment()

  {

  returndepartment;

  }

  publicvoidsetGender(intvalue)

  {

  gender=value;

  fireObservedChange("gender",value);

  }

  publicvoidsetId(Stringvalue)

  {

  id=value;

  fireObservedChange("id",value);

  }

  publicStringgetError()

  {

  returnerror;

  }

  publicvoidsetSname(Stringvalue)

  {

  sname=value;

  fireObservedChange("sname",value);

  }

  publicvoidsetDepartment(Stringvalue)

  {

  department=value;

  fireObservedChange("department",value);

  }

  publicvoidformSubmit(IRequestCyclecycle)

  {

  //判断用户是否添完了所有数据

  if(gender==0||id==null||id.equals("")||sname==null||sname.equals("")||

  department==null||department.equals(""))

  {

  error="请填充完所有选项";

  return;

  }

  //将学生保存

  try{

  Studentstudent=newStudent();

  student.setId(id);

  student.setName(sname);

  if(gender==1)

  student.setGender("男");

  else

  student.setGender("女");

  student.setDepartment(department);

  student.save(null);

  }catch(Exceptione){

  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组件中就使用了privateassets,而这些图像文件就放在WAR的WEB-INF/classes下,注意图像跟html一样也有多个语言的版本。

  注意jwc文件中的inputLocale这个组件,其实localization应用就是通过这个组件来实现本地化。具体参数请看其Developerguide。

 

 

 

 

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

  tapestry的功能非常强大,本文只是介绍了其一小部分,还有很多方面没有涉及到,例如javascript在tapestry中的应用。具体可以看其文档,相信如果你用一下这个框架,你就会被它深深吸引。tapestry的文档做的不是很全,不过经过不断的摸索,相

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值