Web框架层是一个清洁的楼层。很多优秀的程序员在这一层大展身手,做出了很多好作品。我感觉不错的有Spring MVC, Web Work。
对于Web应用来说,Web框架层是最重要的一层。SOA、Semantic Web等效果都要在这一层实现。
首先,我们来讨论,框架的编程结构。
我的Blog中有一篇《Java Web框架综述》的文章。讲解了一些流行的Web框架的编程结构,很多重复的内容不再赘述。

Java Web框架综述
/archive/2004/12/21/224069.aspx

Spring MVC的编程接口是最清晰的。大多数简单情况下,Web Work的用法是最简单有效的,编程结构比较特殊,可以说具有一定的变革意义。
Spring MVC的Controller接口相当于Struts Action,也具有Request, Response两个参数,虽然编程接口非常清晰优雅,但是本质上没有什么变化。
WebWork的Action则失去了Controller的身份,只相当于FormBean的身份,或者说相当于ActionBean的身份。WebWork Action不具有Request, Response两个参数,它只具有属性,并通过属性Setter获取HTTP Request的参数,通过属性getter把结果数据输出到HTTP Response。
可以说,WebWork的这个把握是相当到位的。95%以上的情况下,程序员是不需要Request, Response参数的。当需要这些参数的时候,WebWork并没有挡住路,可以通过实现RequestAware,ResponseAware等接口来获取,或者通过一个Thread Local获取。这种情况下,编程结构的约定,就不那么清晰了。

我从Canonical的帖子和Blog受到了很多启发。
http://canonical.blogdriver.com

jsplet:对Model 2模式的批判
http://canonical.blogdriver.com/canonical/591479.html

jsplet与webwork的概念对比
http://canonical.blogdriver.com/canonical/594671.html

从级列理论看MVC架构
http://canonical.blogdriver.com/canonical/579747.html

从Canonical的文章可以看出。JSPLet用JSP文件作为Dispatcher,然后在JSP里面注册并调用对应的Object。这个寻访Object的过程,完全是根据丰富的URL定义来做的。URL里面包括Object Scope, Object Name, Method Name, Method Parameters,天生就对事件机制有良好的支持。

Zope的一些做法也有异曲同工之妙。
Zope Object Publishing
http://www.zope.org/Documentation/Books/ZDG/current/ObjectPublishing.stx http://www.plope.com/Books/2_7Edition/ZopeArchitecture.stx#2-3

这种通过URL获取Published Object的服务的思路,是一种实现SOA效果的有效思路。

我们首先来看Web Service的现状。目前Web Service主要分为两大阵营。SOAP和REST。关于REST,请参阅
http://www.xfront.com/REST-Web-Services.html 关于SOAP和REST的比较、互操作,网上有很多文章。如果需要请搜索查阅。

我个人比较倾向于REST风格的Web Service。
因为SOAP是一门固定的协议,如果用SOAP来编写Web Service程序,需要一个SOAP协议的解析库 ,也许还需要一些专门的“SOAP 数据 -- 编程语言”映射库,如同CORBA IDL的多语言映射一样。如果你要让自己的Web应用支持SOAP,你需要把发布的服务对象、方法都包装为SOAP协议,这需要一些编程语言相关的数据结构的映射工作。
REST则只是一种风格,而不是一个协议。中心思想是简单的通过丰富的URI定义 (如XLink + XPointer等) 获取资源。如果你要让自己的Web应用支持REST,那么很简单,只要在URI上下功夫就可以了,比如,多增加一个参数format=REST,在程序中多增加一种XML输出格式就可以了。(从道理上来说,SOAP也可以这么实现,但SOAP的输入和输出都要遵守SOAP协议,SOAP的输入参数一般都包装在SOAP信封里面)

关于HTTP Get和Post,我表述一下自己的看法。
我认为,Web的精髓在于Get,而不是Post,在于获取服务器的输出,而不是输入到服务器。即,Web的精髓在于以小搏大,四两拨千斤。最经典的用法就是用一个URL,获取一个长篇的文本内容,这个内容里面充满了其他更多的资源连接。这也是超文本连接HTML发明的初衷。
至于HTTP Post,则是这上面的一个扩展。B/S结构如此流行,很多应用都要转移到Web上面,怎么办,应用总是交互的,总要让用户输入数据吧,就增加了HTTP Post协议。
HTTP Get经典、简单、有效。可以用丰富的URI定义把这个优势发挥到极致。这个实现也比较简单、优雅。就不多说了。主要的难点在于HTTP Post。下面的讨论主要应对“HTTP Post”这个复杂现象。
HTTP Post从来就不让人们满意。当输入逻辑复杂到一定程度,表单数据的繁杂、凌乱、散落,到了服务器端很难组织起来。输入方面B/S结构确实和C/S结构难以匹敌。于是,出现了XMLHttp,能够把参数在浏览器里面组织成为一个统一的XML数据结构(或其他格式),发送到服务器端,一次解析出来。SOAP做这个方面,更是拿手好戏。所以,很多XMLHttp程序直接采用SOAP作为通信协议。而REST风格的HTTP Post则和HTML Form Post没有太大的本质区别。
REST在HTTP Get方面更胜一筹,SOAP在HTTP Post方面更胜一筹。可以根据Web应用的特点,根据HTTP Get / HTTP Post 页面的比例,选择适合的技术。
我们再进一步分析HTTP Post的数据内容。HTTP Post的数据,可能包含三种类型:
(1) 需要存档在服务器的数据
比如,用户注册时候,输入的基本信息,用户名、密码、电子邮件等。这些信息要存放到服务器的数据库。
对于这种基本信息,HTTP Post,XMLHttp,SOAP处理起来,难度都不大,没有很大区别。
B2B的数据交换,也属于这个类别。用何种技术区别不大。一般采用SOAP,因为SOAP是一种流行的标准协议。
(2) 服务调用参数
比如,用户进行复合条件查询的时候,输入的查询条件。这个时候,HTTP Post处理起来就非常蹩脚。而XMLHttp,SOAP则具有很大的优势。可以把复杂的查询条件很好组织成XML数据,发送到服务器端统一处理。SOAP里面甚至可以定义对象名、方法名等详细的调用信息。
(3) 指令
这种情况比较少见。上面的参数类别中提到的“对象名、方法名等详细的调用信息”,和这个指令类别有些交叉。
假如一个SOAP调用方法里面的参数也是一个自定义的对象,这个自定义对象的属性数据在SOAP信息中进行了定义。到了服务器端之后,服务端程序首先调用这个自定义参数的构造函数,生成这个参数对象,然后调用对应的服务对象,把这个参数传给服务。这个过程可以看作是一个顺序指令:[1]构造参数[2]调用服务。
这只是最简单的情况。而目前的Web Service一般也就支持到这个程度。
我的看法是,一不做,而不休。既然都把调用信息定义到这个程度了,不如做的更彻底一些,全面完善的支持指令。这个指令则意味着逻辑。前面讲过了,我不赞成用XML Tag表示逻辑,而赞成脚本。这里比较适合的脚本是JavaScript,因为JavaScript比较通用,客户端、服务器端都可以解释执行。注意,这里和一般的做法正好相反:一般的Web应用总是把JavaScript从服务器传到浏览器里面执行,而这里是把JavaScript在浏览器里组织好,发给服务器端处理;这个JavaScript将会在服务器端执行,调用服务器端的对象。举个SOAP含有JavaScript指令的例子 (只是示意,非标准格式) :

<soap envelope> 
<XML Data> 
<a> 
<b>12</b> 
</a> 
<c> 
<d>21</d> 
</c> 
<e> 
<e>16</e> 
</e> 
</XML Data><script> 
final_result = default; 
result1 = service1.service(a.b); 
if(result1.ok){ 
result2 = service2.service(c.d); 
if(result2.ok) 
final_result = service3.service(e.f); 
} 
</script> 
< /soap envelope >

这个好处是:
[1] 发布了更多的基本Service。给客户提供了更大的灵活度。
比如,这里就发布了3个Service。由用户自己组织逻辑。
按照传统的做法,上述流程将整个包装在服务器端执行。发布给用户的Service只有最外面的一个Service,而且高度耦合(if, else, if, else流程hard code在服务器端),不灵活,不通用。
这里的方法,就可以让客户端随意组织service1, service2, service3的调用顺序和方式。
[2] 减少了通信次数。
假如这段Script在客户端执行,那么和服务器要进行3次通信。

传统Web的权限控制一般在URL级别,这种script -> server方式的权限控制则要在对象级别、方法级别、Code片断级别了,复杂很多,也许要大量应用Java的Code权限认证机制。

以上展开讨论了 Web Service, HTTP Get/Post。下面我们回到Web框架层。
前面说了,JSPLet给了我很大的启发。很多思路可以借鉴。
当然,我并不赞成用JSP作Dispatcher, Controller。(1) 因为JSP要编译成Servlet,而Servlet是Web Server管理的比较昂贵的资源。一个Web系统中JSP达到几千个,就会遇到性能瓶颈。(2) JSP中的代码重用很成问题。一般只能通过include file的方式。
可以借鉴的思路。(1) JSPLet 的入口是JSP文件,这一步的URL到处理程序的映射是Servlet/JSP Container自然支持的。这是免配置的。(2) 丰富的URL参数定义,良好的对象方法寻址能力。