Java Web开发构想(4) -- 6. Web框架

6Web框架

Web框架层是一个清洁的楼层。很多优秀的程序员在这一层大展身手,做出了很多好作品。我感觉不错的有Spring MVC, Web Work

对于Web应用来说,Web框架层是最重要的一层。SOASemantic Web等效果都要在这一层实现。

首先,我们来讨论,框架的编程结构。

我的Blog中有一篇《Java Web框架综述》的文章。讲解了一些流行的Web框架的编程结构,很多重复的内容不再赘述。

http://blog.csdn.net/buaawhl

 

Java Web框架综述

http://blog.csdn.net/buaawhl/archive/2004/12/21/224069.aspx

 

Spring MVC的编程接口是最清晰的。大多数简单情况下,Web Work的用法是最简单有效的,编程结构比较特殊,可以说具有一定的变革意义。

Spring MVCController接口相当于Struts Action,也具有Request, Response两个参数,虽然编程接口非常清晰优雅,但是本质上没有什么变化。

WebWorkAction则失去了Controller的身份,只相当于FormBean的身份,或者说相当于ActionBean的身份。WebWork Action不具有Request, Response两个参数,它只具有属性,并通过属性Setter获取HTTP Request的参数,通过属性getter把结果数据输出到HTTP Response

可以说,WebWork的这个把握是相当到位的。95%以上的情况下,程序员是不需要Request, Response参数的。当需要这些参数的时候,WebWork并没有挡住路,可以通过实现RequestAwareResponseAware等接口来获取,或者通过一个Thread Local获取。这种情况下,编程结构的约定,就不那么清晰了。

 

我从Canonical的帖子和Blog受到了很多启发。

http://canonical.blogdriver.com

 

jsplet:Model 2模式的批判

http://canonical.blogdriver.com/canonical/591479.html

 

jspletwebwork的概念对比

http://canonical.blogdriver.com/canonical/594671.html

 

从级列理论看MVC架构

http://canonical.blogdriver.com/canonical/579747.html

 

Canonical的文章可以看出。JSPLetJSP文件作为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主要分为两大阵营。SOAPREST。关于REST,请参阅

http://www.xfront.com/REST-Web-Services.html

关于SOAPREST的比较、互操作,网上有很多文章。如果需要请搜索查阅。

 

我个人比较倾向于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 GetPost,我表述一下自己的看法。

我认为,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没有太大的本质区别。

RESTHTTP Get方面更胜一筹,SOAPHTTP Post方面更胜一筹。可以根据Web应用的特点,根据HTTP Get / HTTP Post 页面的比例,选择适合的技术。

我们再进一步分析HTTP Post的数据内容。HTTP Post的数据,可能包含三种类型:

(1) 需要存档在服务器的数据

比如,用户注册时候,输入的基本信息,用户名、密码、电子邮件等。这些信息要存放到服务器的数据库。

对于这种基本信息,HTTP PostXMLHttpSOAP处理起来,难度都不大,没有很大区别。

B2B的数据交换,也属于这个类别。用何种技术区别不大。一般采用SOAP,因为SOAP是一种流行的标准协议。

 (2) 服务调用参数

比如,用户进行复合条件查询的时候,输入的查询条件。这个时候,HTTP Post处理起来就非常蹩脚。而XMLHttpSOAP则具有很大的优势。可以把复杂的查询条件很好组织成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。给客户提供了更大的灵活度。

比如,这里就发布了3Service。由用户自己组织逻辑。

按照传统的做法,上述流程将整个包装在服务器端执行。发布给用户的Service只有最外面的一个Service,而且高度耦合(if, else, if, else流程hard code在服务器端),不灵活,不通用。

这里的方法,就可以让客户端随意组织service1, service2, service3的调用顺序和方式。

[2] 减少了通信次数。

假如这段Script在客户端执行,那么和服务器要进行3次通信。

 

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

 

以上展开讨论了 Web Service,  HTTP Get/Post。下面我们回到Web框架层。

前面说了,JSPLet给了我很大的启发。很多思路可以借鉴。

当然,我并不赞成用JSPDispatcher, Controller(1) 因为JSP要编译成Servlet,而ServletWeb Server管理的比较昂贵的资源。一个Web系统中JSP达到几千个,就会遇到性能瓶颈。(2) JSP中的代码重用很成问题。一般只能通过include file的方式。

可以借鉴的思路。(1) JSPLet 的入口是JSP文件,这一步的URL到处理程序的映射是Servlet/JSP Container自然支持的。这是免配置的。(2) 丰富的URL参数定义,良好的对象方法寻址能力。

 

我开发的开源Web框架lightweb,将具备如下特性:

(1) 支持两个层次的编程接口。

interface Action {  void service(request, response, servletContext);  }

这个ActionStruts Action, Spring MVC Controller高一个级别。相当于Dispatcher, 相当于JSPLetJSP控制文件。这个用来做最外层的入口控制。

同时,也支持简单的JavaBean.method的直接调用。相当于WebWork ActionJSPLet Registered Object。这个用来做具体的事情。

 

(2) 支持丰富的对象寻址URI,比如http://my.com/myProject/myModule/myEntry.action?object=calculator&method=add&p1=1&p2=3

这表示要通过 myEntry.acion这个入口,调用caculator.add(1, 2)方法。

如果用URL Rewriter可以美化为

http://my.com/myProject/myModule/myEntry/calculator/add/1/3

看起来就很象XLink + XPointer了。

 

(3) 免配置。或者说极少的配置。

框架根据一定的匹配准则,把myModule/myEntry.action映射到

com.mycompany.mymodule.MyEntryAction 这个类的service方法。

这个service方法负责根据object, method的名字,寻找到对应的bean,并根据参数进行属性设置验证,并执行对应的bean.method。然后,把这个bean作为Modeltemplate结合,输出结果。

同样,template的获取也是根据一定的匹配准则,根据myModule/myEntry找到

Mymodule/myentry.html 或者Mymodule/myentry/calculator.html

 

这样的lightweb就能够同时对应简单和复杂。复杂控制的需求交给Action接口来做,简单的一般具体任务交给普通Java Bean去做。

Web框架层可以做的非常复杂,可以做的非常简单。Lightweb的目标,就是分成多个简单的部分;各部分合起来就能够完成从非常简单到非常复杂的需求。

接下来,我们来看O/R

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值