Web页面技术综述(包括fastm)

Web页面技术综述(包括fastm)

1. 序
Java Web Application中,页面生成部分是最繁琐、令人头痛的部分。
其它的层都可以很好的结构化,唯有页面生成部分的结构很散乱。

本文首先介绍并比较各种页面生成技术,然后具体介绍作者的一个把PHP 模板改进到Java的开源项目――fastm。
我希望fastm能够帮助广大Java Web程序员从繁琐的页面开发工作中解脱出来。

2.页面生成技术综述
本文所指的页面是XML,HTML,WML等能在浏览器中显示的Web页面。
按照页面处理逻辑的位置划分,页面生成技术可以分为两大类:

(1)一类是,页面本身包含逻辑(if, for, etc)。比如,JSP + TagLib, Velocity, XML + XSLT(处理逻辑在XSL文件中),Tapestry等。
这一类技术中,由于页面本身包含逻辑,页面组件的结构和可重用性都不是很好,无法使用“对象” 、“类”、“包”等面向对象的特性。

(2)另一类是,页面本身不包含逻辑。比如Echo,XMLC,DOM + XPath,Echo,PHP,JDynamicTe, fastm等。
这一类技术中,由于处理逻辑在Java Code里面,所以,Java程序的结构和可重用性能有多好,页面组件的结构和可重用性就能有多好。

下面分别讲解和比较这些页面生成技术:

2.1.JSP + TagLib
JSP + TagLib 是Sun公司的页面生成技术规范。

优点:
权威,规范,使用者众多,第三方提供了大量的TagLib支持。
而且,JSP本质上是Servlet。其中的Java Code部分非常强大而且灵活,能够达到Java语言最大的灵活度。
TagLib能够达到一定程度上的页面元素重用。TagLib还能够在一定程度上,帮助驱逐JSP页面的Java Code“污染”部分。

缺点:
JSP的缺点很明显。Java Code和HTML页面内容混杂在一起,这是让广大程序员最头疼的Java Code Pollution问题。即使用TagLib也不能完全解决这个问题。
而且,程序员和页面编辑人员无法在同一个文件上工作。每次页面编辑人员编好了HTML页面,程序员必须重新加入Java Code和TagLib。
而HTML页面一旦加入了Java Code和TagLib,就无法在页面编辑器(Dream Weaver, Front Page)中正确显示了。程序不跑起来,就无法看到JSP页面的页面结构、显示风格和内容。
关于效率,灵活性,结构性,可重用性,JSP + TagLib是一个两难的选择。
在JSP中大量的使用TagLib,能够使得JSP的页面结构良好,更符合XML格式,而且能够重用一些页面元素。但TagLib的编译之后的代码庞大而杂乱,而且运行效率很低,严重影响响应速度。TabLib很不灵活,能完成的事情很有限。TabLib代码本身的可重用性受到TagSupport定义的限制,不是很好。TagLib的编写不是一件愉快的事情。
如果在JSP中大量使用Java Code,那么页面的结构性会很差,难以管理。所有的代码都在同一个文件中,遇到大的HTML页面,简直如同噩梦一般。从一个左括号“{”找到对应的右括号“}”都变成很痛苦的一件事情。镶嵌在Java Code中间的HTML元素的是无法重用的。所以,除了Include file或者jsp:include,JSP中的Java Code根本就没有可重用性。

2.2.Velocity
http://jakarta.apache.org/velocity/

Velocity是一种模板处理工具。Velocity模板由HTML中夹杂一些Velocity脚本语言或变量定义组成。

优点:
Velocity的脚本语言(以开始)或变量定义(用$标志)和HTML、WML、XML等的元素定义不冲突。
简单的Velocity页面(不包含分支和循环逻辑)能够在页面编辑器(Dream Weaver, Front Page)中正确显示。

缺点:
同样,Velocity模板的页面处理逻辑和HTML元素混杂在一起。如果Velocity页面的逻辑复杂的话(比如有循环和判断分支),那么该Velocity页面同样不能在页面编辑器(Dream Weaver, Front Page)中正确显示。
遇到大的HTML页面,从一个 “if”找到对应的 “end”也是很痛苦的一件事情。镶嵌在Velocity脚本语言中间的HTML元素的是无法重用的。所以,Velocity模板中的脚本代码和HTML元素也不具有可重用性(include file除外)。

2.3.XML + XSLT

http://cocoon.apache.org/

Cocoon项目采用XML + XSLT的方法。Java程序只需要输出XML数据,Cocoon框架调用XSL文件把XML数据转换成HTML、WML等文件。

优点:
程序员省事了,不用考虑页面结构和显示方式,只需要输出XML数据即可。
同一份XML数据,只要定义不同的XSL文件,就能够很方便地产生不同显示风格的页面。
在内容和显示风格分离的方面,XML + XSLT这种方法做得最好。

缺点:
慢。XSLT的速度比较慢。
由于没有HTML文件,根本看不到页面结构、显示风格和内容。只有程序跑起来,XSLT转换之后,才能
XSL语法比较难以掌握,由于没有“所见即所得”编辑工具,学习成本较高,远远高于HTML的学习成本。

2.4. Tapestry

http://jakarta.apache.org/tapestry/

Tapestry扩展了HTML元素的定义。Tapestry用这些扩展的HTML元素属性来表示处理逻辑(循环,分支等)、组件定义和变量定义。

优点:
整个Tapestry页面文件都是HTML元素,能够在页面编辑器(Dream Weaver, Front Page)中显示。但显示的样子是否正确,是另一回事,和包含的处理逻辑(循环,分支等)的复杂度相关。大致和Velocity的情况相似。
Tapestry的页面组件重用性比较高。

缺点:
复杂。Tapestry的定义和用法都很复杂。由于复杂,所以慢。

我没有实际使用Tapestry的具体经验,这里就不继续妄加评论了。

2.5. XMLC

http://xmlc.enhydra.org/

XMLC把HTML、WML等文件编译成一个DOM结构的Java类。程序员不用管页面,只需要操作这个DOM结构,就可以动态生成页面。
XMLC根据HTML元素的id定义,生成相应结点的操作方法。

优点:
页面是纯粹的HTML,没有任何逻辑。能够在页面编辑器(Dream Weaver, Front Page)中正确显示。
Java Code处理DOM结构,代码结构和可重用性良好。DOM节点即HTML元素,即页面组件,也具有很好的可重用性,你随时可以把一个DOM节点放到任何文档中的任何位置。
由于是静态编译,没有动态解析过程,文档生成的速度很快。

缺点:
每次修改HTML页面,必须重新把HTML文件编译成Java文件。而且,很多HTML都不是良好的XML结构,不能够正确地编译成DOM结构。
该DOM结构不能在多线程环境中重复使用,这就意味着,每一个页面请求,都需要生成一个单独的DOM结构,占用内存空间比较大。而且,每个DOM结构使用过之后,也很难清空重置,很难提供给下一个请求使用。在HTML文件比较大的时候,内存的开销显著增大。
XMLC有些方面不够灵活。比如,我们知道,很多Java Script方法定义在XML注释当中。比如:
<SCRIPT LANGUAGE="Javascript" type="text/javascript">
<!--
function aa{

}
//-->
</SCRIPT>

如果Java Script中有需要动态生成的部分,而注释部分的Java Script不是XML结构,XMLC很难处理这种情况。

2.6.DOM + XPath
前面讲了XMLC把HTML静态编译成DOM结构。
我们也可以采用动态生成DOM结构的方法,然后用XPath定位DOM结点并操作它们。
NekoHTML(http://www.apache.org/~andyc/neko/doc/html/)是一个HTML文档解析工具。
NekoHTML使用Apache Xerces(http://xml.apache.org/xerces2-j/index.html)的Xerces Native Interface对HTML文档进行解析,能够自动补足并修正不符合XML文法的HTML元素,并生成HTML DOM文档树。
Apache Xcerse的XPathAPI,可以用XPath方便地定位DOM结构的结点。DOM + XPath的详细用法请参见NekoHTML的使用文档。

优点:
大致具有上述XMLC方法的优点。
没有静态编译过程,动态生成DOM结构,及时反映页面文件的变化。

缺点:
大致具有上述XMLC方法的缺点。
DOM结构的动态生成比较花时间。我们可以采用这样的方法解决这个问题,把第一个生成的DOM结构作为标准模板。我们不对标准模板操作,每次请求需要一个DOM结构的时候,我们就从这个标准模板深度拷贝(deep copy)一个新的DOM结构,然后使用这个新的DOM结构。这样每个HTML文件只需要解析一次,成为标准模板。每次HTML文件更改的时候(这种情况很少),标准模板也跟着更新。
XPath的解析和定位速度不是很快,几乎每次都要遍历整个文档树。

2.7.Echo

http://sourceforge.net/projects/echo

Echo项目中不用定义模板文件。程序员按照Swing的方式写代码,Echo帮助你生成HTML结果。

优点:不用处理HTML部分。Swing是可重用性极好的真正组件。

缺点:Echo把HTML屏蔽起来,自动生成了很多JavaScript和HTML代码。对于Web程序来说,不够灵活,难以维护。

2.8. PHP

PHP模板的设计思路很好,PHP模板用XML的Comment注释部分来定义动态结构,用{}来标志需要替换的变量部分。

优点:
页面编辑器(Dream Weaver, Front Page)不显示XML的Comment注释部分,而且{}符号和XML元素定义不冲突。所以,PHP模板本身符合HTML语法,能在页面编辑器(Dream Weaver, Front Page)中正确显示。程序员和页面编辑人员可以在同一份页面文件上工作,所见即所得。
简单,易用,灵活(几乎和最灵活的JSP Java Code一样灵活)。具体用法见后面。本文的主要目的就是介绍PHP模板及其Java Port的用法。

缺点:
比起其它的页面技术来说,这种技术的缺点很少。
一个需要提到的地方,也是Java Script方法定义在XML注释当中的情况。比如:
<SCRIPT LANGUAGE="Javascript" type="text/javascript">
<!--
function aa{

}
//-->
</SCRIPT>
因为PHP Template采用XML Comment来定义动态结构,所以我们不能在Java Script中定义结构。但我们不需要在XML Comment中定义动态结构,我们可以用{}标志需要动态改变的地方,完全能够达到同样的目的。

2.9 JDynamiTe

http://sourceforge.net/projects/jdynamite

从各方面来说,我认为PHP是最好的页面生成技术。
我的一个同事向我介绍了PHP Template的定义和用法,我产生了浓厚的兴趣,并产生了把PHP Template移植到Java的想法。我首先到网上搜索了一下,发现了JDynamiTe (Java Dynamic Template) (https://sourceforge.net/projects/jdynamite)开源项目。JDynamiTe能够把PHP模板移植到Java语言。

JDynamiTe的模板定义和PHP Template有些微小的差别,但一样简单。我阅读了JDynamiTe的例子代码,马上喜欢上了这种方法。

但我发现,JDynamiTe有一点不足。和DOM结构的处理过程一样,JDynamiTe的模板部分和参数设置部分是合在一起的。JDynamiTe的模板部分不能在多线程中同时使用。
每次JDynamiTe都需要读取并解析HTML文件,生成一个模板,设值之后,产生结果。处理过后的这个模板就不能再直接使用了(也许可以清空再使用)。
如果HTML文件很大,那么,读取并解析HTML文件要花费不少时间。

所以,我决定自己实现一个高效率的可重用的PHP Template Java Port。
项目名为fastm(Fast Template的意思。)

2.10. fastm

http://sourceforge.net/projects/fastm


http://sourceforge.net/projects/lightweb

fastm的模板定义采用JDynamiTe的模板定义,而且我直接采用JDynamiTe的例子模板文件,作为fastm测试例子的模板文件。fastm可以说是JDynamiTe的一个Multiple Thread Port。
在fastm里,我把HTML的解析结果文档 (Template DOM)和变量设值部分(ValueSet DOM)分开。
每个HTML文件只需要解析一次,生成一个只读的模板。既然只读,当然线程安全,任何数量的线程都可以同时使用这个模板。
以后这个模板只需要和不同的变量设值结合,就可以生成不同的结果。
模板的解析过程,采用按行读取处理的方式,解析的速度很快。

fastm的速度会比JSP + TagLib快。fastm的速度可能会比纯粹的JSP慢,也可能更快一些。JSP(即Servlet)把整个页面一行一行地写到Response里面,网络传输的效率不高(当然,也有可能用到HTTPResponse的buffer)。而fastm把整个页面或者整块页面,一次写到Response里面,网络底层协议尽可以优化分块,达到最好的网络传输效率。

fastm支持动态生成JavaScript。这是PHP和JDynamiTe无能为力的地方。
fastm支持JavaScript的注释定义。比如,
// BEGIN DYNAMIC: special_code
…..
// END DYNAMIC: special_code

这一块将被标志为动态块。

fastm的页面定义完全仿照JDynamiTe的PHP页面定义。我的思路来源是PHP Template和JDynamiTe。我自己原创的东西是fasm的实现,和使用方法。fastm的代码量很小,采用的技术也很简单,没有用任何第三方的软件,只用了JDK1.4本身的类。

fastm是DOM & PHP思路上的又一次飞跃――Template DOM 和ValueSet DOM的分离。

在我目前所知的Java页面生成技术中,我相信,fastm从各方面来说,是最好的方法――快,易用,灵活,强大。我期望fastm这种页面生成方式,能够较好地解决页面生成技术这个令人头痛的问题,能够在全世界的程序员中流行起来。

fastm设计思路深度剖析

1.PHP(&fastm)把文档切割为简单的DOM结构

PHP模板的设计思路非常漂亮,用注释里的Begin和End把HTML(WML,或任何XML)页面切割成不同的块,而且块里面还可以继续切块。
这样一来,一个页面被切割成一个树结构,很象DOM结构。只是DOM结构太过笨重,对每一个元素都要建立一个节点,而且节点的类型非常复杂。比如,一个HTML DOM结构,有多少种HTML元素,就会有多少种节点类型,比如,Body,Table,TR,TD,Form,Input等。
而PHP模板则是一个轻量级的DOM结构,一个Begin-End块就是一个节点。Begin-End块只包括三种内容――静态文本,变量,和其它的Begin-End块。
设计思路如此简洁而强大,易用而通用(可以用在任何规范或不规范的XML页面中,比如HTML,WML,甚至XUL,XAML),而且,能够在HTML编辑器中所见即所得。纵观天下模板技术,莫出其右。
我经过了多种Java页面技术的折磨,经同事介绍,认识了PHP模板技术,欣喜异常,原来竟有这样的好东西,只恨相识太晚。
Fastm模板的思路完全借鉴PHP模板思路,只是稍微做了一些扩展。(详情请参见我的上一篇提到JDynamiTe的文章――Java页面技术综述)。
Fastm模板的BEGIN-END DYNAMIC块,就相当于PHP模板的Begin-End块。
Fastm模板的BEGIN-END IGNORED块,就相当于PHP模板的忽略不显示的Begin-End块。
比如下面的HTML片断。


<select name=”zipcode”>
<!-- BEGIN DYNAMIC: zipcodes -->
<option value=”{zipcode}”>{zipcode}</option>
<!-- END DYNAMIC: zipcodes -->
</select>

我们看到,这个片断包含一个BEGIN-END块(zipcodes),这个块里包含两个相同的变量{state},其它的部分都是静态文本。

这个片断的fastm Template DOM结构如下:


静态文本 <select name=”zipcode”>
动态块zipcodes --
| --- 静态文本 <option value=”
| --- 变量{zipcode}
| --- 静态文本 ”>
| --- 变量{zipcode}
| ---静态文本 </option>
静态文本 </select>


2.fastm的ValueSet是DOM概念的又一次飞跃

Fastm模板DOM结构的一个核心特性就是,只能读取,不能改变。

PHP代码每次装载一块PHP模板,然后动态更换里面的变量部分的值。PHP模板从本质上讲是可以读取,也是可以操作改变的。
HTML(WML,XML)DOM更是如此。程序直接修改DOM节点的值,才能得到不同的动态结果。可以说,XML DOM天生就是用来操作改变的。XML DOM本身又是模板,又是数据。

可以改变的DOM结构不能够用在多线程的环境下。每个线程必须获取自己的新鲜DOM备份,进行操作改变,得到自己的动态结果。想想看,在一个静态文本占绝大部分的DOM结构里,这种做法将造成多么大的空间和时间上的浪费。

Fastm模板的DOM结构是只读的,不能改变。所以一个Fastm DOM可以用在多线程的环境中。
既然我们不能改动Fastm Template DOM,那么我们如何给Fastm Template DOM赋值呢?我们如何利用Fastm Template DOM获得动态结果呢?
Fastm引入了ValueSet的概念。ValueSet是一个树形结构的动态数据集,用来匹配只读的Fastm模板DOM结构,生成动态结果。
程序员必须事先构造好整个树形动态数据集(ValueSet DOM),然后把和ValueSet DOM和Fastm Template DOM结合起来,生成动态结果。

所以,fastm的整个使用如下:
(1)程序的整个运行过程中,fastm模板文件(也就是加了BEGIN-END注释的HTML文件)只需要被解析一次,生成一个Fastm Template DOM。
(fastm模板解析速度奇快,比JSP编译,Velocity解析,XML DOM解析,都快很多,大部分情况下甚至快于SAX解析。而且fastm DOM和原始fastm模板文件的大小几乎一样大,只多了一个List记录不同的块,空间效率也要高出)
(2)程序生成不同的ValueSet DOM,匹配只读的Fastm DOM,生成不同的动态结果。
(由于fastm Template DOM结构的简单高效,整个匹配过程很快。通常情况下,时间效率甚至高于最快的纯JSP或Servlet。ValueSet DOM的空间效率比不上纯JSP或Servlet,但经过合理重用,至少可以接近纯JSP或Servlet的空间效率。以后的高级应用话题系列会详细讲解这个问题。)

比如,我们来为上面的Template DOM结构(zipcode Select)构造一个ValueSet DOM。

String[] zipcodes = {“361005”, “100008”};

IValueSet top = new ValueSet(); // 对应上面的整个HTML片断
List items = new ArrayList(); // 对应 动态部分zipcodes
for(int i = 0; i < zipcodes.length; i++){
IValueSet item = new ValueSet();
item.setVariable(“{zipcode}”, zipcodes[ i ]);
items.add(item);
}

top.setDynamicValueSets(“zipcodes”, items);

我们把top这个ValueSet DOM和Template DOM结合起来。就生成如下结果。


<select name=”zipcode”>
<option value=”361005”>361005</option>
<option value=”10008”>100008</option>
</select>

我们可以看到,Template DOM节点和ValueSet DOM节点之间不是一一对应的关系,而是一对多的关系。一个Template DOM节点对应一个ValueSet List。ValueSet List包含多少个ValueSet,这个Template DOM节点就显示所少次。

比起TagLib来,fastm的优势显而易见。fastm的几行代码,或者一个方法,可以实现一个或几个TagLib的功能。比起任何其它的页面技术来说,其它页面技术能做到的,或者做的好的,fastm都能够做得到,而且做的更好。而fastm能做到很多其它页面技术做不到的事情。好了。不多说了。

ValueSet DOM和Template DOM的分开,是一个极大的思路上的创新和飞跃。
毕竟,页面中的动态部分,和静态比起来,是非常小的一部分。ValueSet DOM代表动态部分,由程序随时生成,可以存在多份。Template DOM代表静态部分,只需要解析一次,而且只需要一份。

ValueSet DOM和Template DOM的分开,更是一种前所未有彻底的显示和数据的分离。比XML/XSLT的方法更加彻底。XML确实是纯粹的数据,但XSLT中却不可避免的要包含逻辑。ValueSet DOM是纯粹的数据,没有任何逻辑,Template DOM是纯粹的显示模板,也没有任何逻辑。

一份Template DOM可以用多个ValueSet DOM赋值。同样,一个ValueSet DOM也可以用于多个Template DOM,把相同的数据显示在不同风格的模板中。

比如,我们还有这样一个HTML片断:


<table>
<!-- BEGIN DYNAMIC: zipcodes -->
<tr><td>{zipcode}</td></tr>
<!-- END DYNAMIC: zipcodes -->
</table>

我们把上面的top ValueSet赋给这个模板。得到的结果如下。


<table>
<tr><td>361005</td></tr>
<tr><td>100008</td></tr>
</table>

我们可以看到,Template DOM就是模板,只包含显示风格和分块定义。ValueSet DOM就是数据,只包含数据。

Fastm具有其它页面生成技术不可比拟的优越性:
所见即所得,模板与数据的彻底分离,模板与数据的多对多自由匹配,易学易用,开发速度快,运行空间小,运行速度快。
就我个人的感觉来说,fastm简直是解决一切页面技术问题的银弹。

上文可能有些“自卖自夸”之嫌,特解释如下:
我不是一个善于吹嘘的人。否则早就从事推销员、公关宣传之类有前途的职业去了。而且由于自我推销能力和社会关系学能力的欠缺,已经造成了自身的能力、精力和时间上的极大浪费。我痛苦自己的现状,却不后悔。我了解社会的游戏规则,但没有能力,也不愿、不屑参与。内心里总是存在着一种痴心妄想,希望创造一个游离于现有规则之外的奇迹。
另外,我是一个客观求实、头脑严密清晰的人,具有“外举不避仇,内举不避子”的负责的学术精神。有一分,当说一分,决不多说一分,也绝不少说一分。

3.fastm的可重用性的核心在于ValueSet DOM

JSP技术的可重用性的核心在于TagLib。
XML DOM的可重用性的核心在于DOM节点的通用操作。

Fastm的可重用性的核心在于ValueSet DOM节点的通用操作。比如,上面讲的那段生成ValueSet的代码。
Template DOM本身可以作为一个只读模板来使用,同样,Template DOM下面包含有的任何Template DOM结构也可以作为一个独立的只读模板来使用。这点和XML DOM一样。XML DOM的任何一个节点可以作为独立的节点来使用。

ValueSet DOM不仅是数据重用的核心,同样是模板拼装重用的中枢。fastm实现各模板之间各个块的搬运拼装,再容易不过了。实现所谓的Tile功能,小菜一碟。

JSP,还有某些表示逻辑的TagLib,Velocity模板,XSL文件,都是包含逻辑的模板。个人认为,模板中包含逻辑,是一种很可笑的行为。模板的长处在于表现页面布局、显示风格,而不在于逻辑。为什么不让擅长逻辑的Java去处理逻辑?
在fastm中,Template DOM和ValueSet DOM中都不含有任何逻辑。所有的逻辑都落在Java代码中。而Java是一种高度面向对象的语言,其结构性和重用性是任何模板语言不能比拟的。所以,fastm的可重用性的核心在于ValueSet DOM节点的通用操作。这些通用操作的代码当然由Java实现。


fastm资源列表

http://sourceforge.net/projects/fastm

fastm是一个Web页面模板项目。
这个项目下包括两个部分,一个是fastm项目本身,一个是fastm的辅助项目fastmweb,帮助定义装载Web环境中的fastm模板。
如同Velocity一样,用户可以在任何web framework中使用fastm模板技术。

用户可以从这个地址下在fastm和fastmweb的源代码文件、简单的使用文档和jar文件,fastm.jar和fastmweb.jar。

http://sourceforge.net/projects/lightweb

lightweb是fastm作者开发的一个轻量级的Web Framework。
这个项目下包括两个部分,一个是lightweb项目本身,一个是演示程序demo-fastlight。
demo-fastlight演示了如何在lightweb框架中使用fastm,并和jsp程序进行了比较。

用户可以从这个地址下在lightweb和demo-fastlight的源文件、简单的使用文档和jar文件。

其中的demo-fastlight是一个可以直接运行的演示程序。用户下载解开demo-fastlight,可以直接配置在Tomcat(或任何Servlet Server)中运行。

探索精神可佳,不容易,非常辛苦。

别忘记Struts以及JSF,已经可以完成你的心愿了,主流和标准技术还是要关注一下的。


多谢banq的鼓励和关注。

我也一直在关注JSF。并希望JSF能与Visual Studio(ASP.net)一争。

另外,在JDon论坛中看到banq与道友讨论Portal框架和Portlet规范的贴子。受益非浅。多谢。(当然,JDon中还有各种其它的规范和实现讨论,比如Web Service,一并谢过)。

我正是比较了多个框架,多种实现方式,多种开发方式。才产生了实现fastm的想法,以提高开发速度、运行速度,降低学习成本和维护成本。
并且,fastm在实现Layout,Tile,Portal方面,具有先天的优势。

fastm这条方向以前我也思考过,特别是在做网站自动生成时,对于页面动态合作要求很高,使用这种Jsp内嵌特殊语法的做法是可行的。

我的过程是这样:
1. 在Jsp中嵌入特殊语法类似fastm;
2. 使用XML+XSLT结合 类似Cocoon;
3. 最后我发现,Jsp就是一种模板语言,于是又使用Jsp+Taglib方式,正好Struts出现,使用Struts的html:select可以实现你文中的select功能,思路也类似,是在FormBean中做也可以,代码和你的差不多。

现在,结合Struts+Tiles我发现,已经可以把页面定制做得非常灵活了,可以将页面的布局 内容、菜单都可以动态实时变化了,这样实现起来比现在的那些博客weblog仅仅能提供几种模板的选择要自由多,几乎对模板没有限制,可以自行上传自行设计的模板。

我才发现fastm是你自己创造的,非常不容易,更加佩服了。

我需要仔细研究一下你的fastm的特点,现在Web层解决方案很多,各有特点,fastm很有特点,希望能和你继续研究。


多谢Banq的回答。我们的思路经历有些相同。
我甚至想到了要使用SiteMesh。
http://www.opensymphony.com/sitemesh/
SiteMesh是一个基于Servlet Filter规范的一个页面布局工具。
属于opensymphony组织。OSWorkflow,WebWork就属于这个组织。

但后来发现,这样会令问题更加复杂化。
比较探索了各种框架许久。直到了解了PHP,才豁然开朗,找到了思路。

fastm的核心思想是,
(Static Readonly)Template DOM + (Dynamic) ValueSet DOM = Dynamic Template.

其中的Tempate DOM从PHP模板思路而来。
而ValueSet DOM是我为了支持多线程、节省空间和时间,而产生的概念。

我正在做把Struts Tile TagLib的Sample移植到fastm的例子。
还有一些Portal的例子。完成之后,请Bang多指教。

另:
我也在关注JDonJive。
并也有未来把一些Forum移植到fastm的想法。
对于fastm来说,移植PHP Forum更容易一些。因为fastm几乎可以直接使用PHP模板。

PHP其实和Jsp类似,都是一种模板语言,他们嵌套语句的做法也非常相近,一个是{}符号 一个是<%%>符号,由于没有深入比较它们异同,所以感觉它们原理应该是一样的。

JdonJive界面可以使用Fastm实现,其非技术意义要远大于技术本身,你可以给我email,我们讨论这个事情。

buaawhl,我对你的写的fastm很感兴趣,我现在也对这方面进行开发,想和你多交流,你的qq,icq或msn是多少啊?
我的msn是:lwqenter007@hotmail.com