Template和JSP技术2007-05-30 CSDN 一、起源与现状: 关于Template和JSP的起源还要追述到Web开发的远古年代,那个时候的人们用CGI来开发web应用,在一个CGI程序中写HTML标签。在这之后世界开始朝不同的方向发展:sun公司提供了类似于CGI的servlet解决方案,但是无论是CGI还是servlet都面对同一个问题:在程序里写html标签,无论如何都不是一个明智的解决方案。于是sun公司于1999年推出了JSP技术。而在另一个世界里,以PHP和ASP为代表的scriptlet页面脚本技术开始广泛应用。不过即便如此,问题并没有结束,新的问题出现了:业务和HTML标签的混合,这个问题不仅导致页面结构的混乱,同时也使代码本身难以维护。于是来自起源于70年代后期的MVC模式被引入开发。MVC的三个角色:Model——包含除UI的数据和行为的所有数据和行为。View是表示UI中模型的显示。任何信息的变化都由MVC中的第三个成员来处理——控制器。在之后的应用中,出现了技术的第一次飞跃:前端的显示逻辑和后端的业务逻辑分离,COM组件或EJB或CORBA用于处理业务逻辑,ASP、JSP以及PHP被用于前端的显示。这个就是Web开发的Model 1阶段(页面控制器模式)。不过这个开发模式有很多问题:1. 页面中必须写入Scriptlet调用组件以获得所必需的数据。2. 处理显示逻辑上Scriptlet代码和HTML代码混合交错。3. 调试困难。JSP被编译成servlet,页面上的调试信息不足以定位错误。这一切都是因为在Model 1中并没有分离视图和控制器。完全分离视图和控制器就成了必须。这就是Model 2.它把Model 1中未解决的问题——分离对组件(业务逻辑)的调用工作,把这部分工作移植到了控制器。现在似乎完美了,不过等等,原来的控制器从页面中分离后,页面所需的数据怎么获得,谁来处理页面显示逻辑?两个办法:1. 继续利用asp,php或者jsp等机制,不过由于它们是运行在web环境下的,他们所要显示的数据(后端逻辑产生的结果)就需要通过控制器放入request流中;2. 使用新手法——模板技术,使用独立的模板技术由于脱离的了web环境,会给开发测试带来相当的便利。至于页面所需数据传入一个POJO就行而不是request对象。模板技术最先开始于PHP的世界,出现了PHPLIB Template和FastTemplate这两位英雄。不久模板技术就被引入到java web开发世界里。目前比较流行的模板技术有:XSTL,Velocity,JDynamiTe,Tapestry等。另外因为JSP技术毕竟是目前标准,相当的系统还是利用JSP来完成页面显示逻辑部分,在Sun公司的JSTL外,各个第三方组织也纷纷推出了自己的Taglib,一个代表是struts tablib.二、 模板技术分析:模板技术从本质上来讲,它是一个占位符动态替换技术。一个完整的模板技术需要四个元素:0. 模板语言,1. 包含模板语言的模板文件,2. 拥有动态数据的数据对象,3. 模板引擎。以下就具体讨论这四个元素。(在讨论过程中,我只列举了几个不同特点技术,其它技术或有雷同就不重复了)1. 模板语言:模板语言包括:变量标识和表达式语句。根据表达式的控制力不同,可以分为强控制力模板语言和弱控制力模板语言。而根据模板语言与HTML的兼容性不同,又可以分为兼容性模板语言和非兼容性模板语言。模板语言要处理三个要点:1. 标量标记。把变量标识插入html的方法很多。其中一种是使用类似html的标签;另一种是使用特殊标识,如Velocity或者JDynamiTe;第三种是扩展html标签,如tapestry.采用何种方式有着很多考虑,一个比较常见的考虑是“所见即所得”的要求。2. 条件控制。这是一个很棘手的问题。一个简单的例子是某物流陪送系统中,物品数低于一定值的要高亮显示。不过对于一个具体复杂显示逻辑的情况,条件控制似乎不可避免。当你把类似于<IF condition=“$count <= 40”><then><span class=“highlight”>count </span></then></IF>引入,就象我们当初在ASP和PHP中所做得一样,我们将不得不再一次面对scriptlet嵌入网页所遇到的问题。我相信你和我一样并不认为这是一个好得的编写方式。实际上并非所有的模板技术都使用条件控制,很多已有的应用如PHP上中的以及我曾见过一个基于ASP.NET的应用,当然还有Java的JDynamiTe.这样网页上没有任何逻辑,不过这样做的代价是把高亮显示的选择控制移交给编程代码。你必需做个选择。也许你也象我一样既不想在网页中使用条件控制,也不想在代码中写html标记,但是这个显示逻辑是无可逃避的(如果你不想被你的老板抄鱿鱼的话),一个可行的方法是用CSS,在编程代码中决定采用哪个css样式。特别是CSS2技术,其selector机制,可以根据html类型甚至是element的attributes来apply不同的样式。3. 迭代(循环)。在网页上显示一个数据表单是一个很基本的要求,使用集合标签将不可避免,不过幸运的是,它通常很简单,而且够用。特别值得一提的是PHP的模板技术和JDynamiTe技术利用html的注释标签很简单的实现了它,又保持了“所见既所得”的特性。下面是一些技术的比较:
Velocity |
变量定义:用$标志表达式语句:以#开始强控制语言:变量赋值:#set $this = "Velocity"外部引用:#include ( $1 )条件控制:#if …. #end非兼容语言 |
JDynamiTe变量定义:用{}包装表达式语句:写在注释格式(<!-- à)中弱控制语言兼容语言 |
XSLT变量定义:xml标签表达式:xsl标签强控制语言:外部引用:import,include条件控制:if, choose…when…otherwise非兼容语言 |
Tapestry采用component的形式开发。变量定义(组件定义):在html标签中加上jwcid表达式语句:ognl规范兼容语言 |
2. 模板文件:模板文件指包含了模板语言的文本文件。模板文件由于其模板语言的兼容性导致不同结果。与HTML兼容性的模板文件只是一个资源文件,其具有良好的复用性和维护性。例如JDynamiTe的模板文件不但可以在不同的项目中复用,甚至可以和PHP程序的模板文件互用。而如velocity的非兼容模板文件,由于其事实上是一个脚本程序,复用性和可维护性大大降低。3. 拥有动态数据的数据对象:模板文件包含的是静态内容,那么其所需的动态数据就需要另外提供。根据提供数据方式的不同可以分为3种:1. Map:利用key/value来定位。这个是最常见的技术。如velocity的VelocityContext就是包含了map对象。Example.vm:Hello from $name in the $project project.Example.java:VelocityContext context = new VelocityContext();context.put("name", "Velocity");context.put("project", "Jakarta");2. DOM:直接操作DOM数据对象,如XSLT利用XPath技术。3. POJO:直接利用反射取得DTO对象,利用JavaBean机制取得数据。如Tapestry。