原作者: Wicket团队
原文地址:http://wicket.sourceforge.net/wiki/index.php/Struts
Struts
From WicketWiki
| 提纲 |
1.1 概述 |
Wicket与Struts两个框架比较
概述
Wicket是一个基于组件开发的Web程序框架. 其基本优点列表如下:
- 将 HTML与Java 两个开发时的关注点进行分离,有益于程序员与美工的合作开发
- 模型的设计基于面向对象
- 自动管理对象的状态
- 极高的开发效率
- 学习曲线很低
- 通过抽象,封装了Servlet API,HTTP protocol的相关细节
- 基于规则进行配置,不再需要XML文件进行配置
- 很容易开发可重用组件
Struts是一个基于MVC Model2模型的Web程序框架。其基本机制在于通过Action类来处理HTTP请求。通过XML文件进行配置。Struts通常与其它技术(经常为JSP和定制Tag库)联合使用。接下来这篇文章主要描述这两个框架间的区别,并进一步说明Wicket比Struts更优秀的原因(个人观点)。
设计逻辑
Struts其设计方式在于将每一个HTTP请求转化成一个对指定Web程序特定类的请求。每一个Action类都将返回一个结果,该结果将包含下一步流程的相关信息。该结果把请求转到另外一个Action进行处理或者是将请求转给一个JSP页面,最终产生HTML页面反馈给用户。这种方法已经有点不合时适了,原因详列如下:
- 其设计并不基于面向对象的设计,诚然,每一个Action类都是一个抽象的体现,但该抽象更多的时候是由HTTP协议的机制来决定,而并不是基于面象对象的分析。
- 除非你想体验在java代码中输出HTML页面的痛苦,否则你仍然需要了解许多重要技术(包括JSP及定制Tag库)来输出HTML。使用Tag编写的JSP页面因为难以编辑和维护而饱受批评,对于习惯使用可视化开发的人员,这简直不可原谅.
Wicket的方式则完全不同。它完全基于面向对象,和基于组件设计,与Swing相类似。每一个Wicket页面都由许多控件组合而成(设计方式可以参考Composite模式)。借助标记文件(译注:通常为HTML文件),页面和控件负责输出(可以是HTML,译注:也可能是Swing的输出)。当发出HTTP请求后,系统会将相关信息转化成事件,进而将该事件交给相应的Component进行事件触发。所以Wicket解决了Struts设计上的两个问题:
- Wicket完全基于面向对象设计,你可以借助基于控件的继承来设计你的程序。你不要因为要配合 HTPP请求<-->回复这种机制来改变你的OO设计。
- Wicket使用几乎是纯粹的HTML作为标记文件,而且不需要引入额外的内容,与XHTML标准完全兼容(可能要使用Wicket的namespace)。懂HTML就可以编写Wicket的标记文件,即使不懂HTML的人员也可以借助各种工具来编写文件。
处理HTTP请求
在Struts中,当系统收到一个HTTP请求时,就会根据请求所访问的路径在配置文件中查找所映射的Action类。如果配置中指定的ActionForm Bean以及验证要求,系统也会根据请求参数调整Bean的属性并进行验证,(译注:这里指的应该是自动调用Validate方法)。 HTTP请求及回复以及ActionForm都将作为参数传递给Action进行处理。因此从这点上来分析,开发者得用Action对系统进行全面的控制。因此程序员必须手工处理HTTP session信息,并在HTTP请求及回复中控制各种属性。 请求结束时,Action必须返回一个相应的ActionForward以便让Struts框架知道如何进行下一步工作。如果ActionForward要转向JSP页面,程序员还必须编写JSP页面,可能还要使用各种标签库。这是一个费时费力的工作,因为程序员要管理XML配置文件,Java Action类以及定制Tag,不仅容易出错而且降低开发效率。
在Wicket中,当系统收到一个HTTP请求时,Wicket就会根据请求中的信息,找到相应的页面。如果这个请求是通过Form进行提交的,Wicket将会自动抽取参数,并进行验证,然后依照顺序将参数转化成相应的类型,并放入Model中。Wicket将请求转化成各种事件类型,然后以Listener的方式来调用相应的控件,程序员可以在事件代码中代理业务逻辑代码,并设置回复页面。Page类是通过反射进行调用并输出的。render的步骤依次查看页面上每一个控件,并由每个控件来输出自己。每一个控件可以在代码中输出HTML,也可以使用HTML标记文件来输出HTML。在控件与HTML绑定时,唯一要做的就是保证HTML元素属性中的命名(如 wicket:id="id1",译注:目前可以通过命名空间来换成其它方式,如id="wicket-id1")与控件名称相对应。(译注:如果有一个控件的名称为id1,this.add(new Label("id1","Hello")),在HTML页面中应该有一个元素如下 <span wicket:id="id1"></span>,Wicket会自动将其换成 <span wicket:id="id1">Hello</span>)
Wicket框架功能更强的原因如下: