JavaScud | Forum | JIRA | Blog |
  Dashboard > WebWork2文档中文化计划 > ... > Comparison to other web frameworks > Comparison to Struts
  WebWork2文档中文化计划 Log In View a printable version of the current page.  
  Comparison to Struts
Added by scud, last edited by scud on Apr 25, 2006  (view change)
Labels: 
(None)

2005年12月,struts和webwork团队同意合并共同开发Struts Action 2.0, Struts Action 2.0 基于 WebWork 2.2. 所以,下面的比较与这两个社区的合作无关

性能比较

Feature Struts WebWork 1.x WebWork 2.x
Action classes Struts 要求Action类继承一个抽象类.这是Struts针对抽象类而不是接口编程所造成的一个很普遍的问题. Action 类必须实现webwork.Action接口. 也可以实现提供其他服务的接口,如存储错误消息,取得本地化文本等. ActionSupport类实现了其中的一些接口,可以作为一个基类来使用. WebWork全部针对接口编程, 这样很容易插入你自己的实现. 与WebWork 1.x相同,Action必须实现com.opensymphony.xwork.Action接口, 以及一系列的提供其他服务的接口. WebWork2 提供了ActionSupport类实现这些接口.
Threading Model Struts Actions必须是线程安全的,因为Action在处理所有的请求时都只有一个实例.这要求和Struts Actions一起处理的所有资源都要是线程安全的,或者是同步的. WebWork Actions 为每个请求初始化一个实例, 这样就解决了线程安全的问题. 实际上, Servlet 容器每次处理请求时,都会生成许多将被丢弃的对象,但并没有证据证明更多的对象会产生性能或者垃圾回收问题 同WebWork 1.x
Servlet Dependency Struts Actions 依赖于Servlets ,因为Struts Actions 在执行的时候使用了ServletRequest and ServletResponse (并不是HttpServletRequest and HttpServletResponse).这种对于Servlets的依赖事实上是对Servlets容器的依赖,这样的依赖是不必要的.例如, Servlet可以在Web环境之外运行, 但JMS就不能. WebWork Actions 不依赖于web和容器 WebWork actions可以从ActionContext访问request 和response对象,但是这不是必须的,并且最好在绝对需要的时候才去做,以避免对于web层的依赖. 同WebWork 1.x
Testability 已经有许多测试Struts应用的策略,其中最大的障碍是由于Struts Actions对于web层的紧密依赖.(使用Request和Response对象).这导致人们需要在容器内测试Struts Actions.这样做即缓慢又称不上是单元测试. 有一个Junit的扩展 : Struts TestCase (http://strutstestcase.sourceforge.net/) WebWork actions 通过初始化,设置属性,运行你的Action可以很容易的进行测试 同WebWork 1.x, 由于加强了控制翻转(Inversion of Control)的应用使得测试更加简单.你不需要注册服务或者使用静态单例(static singleton),仅仅向你的Action里注入实现服务接口的模拟对象(Mock)就可以进行测试
FormBeans Struts需要对每个表单创建FormBeans, 使得要么增加许多额外的类,要么使用DynaBeans, 而DynaBeans恰恰是这一限制的产物 WebWork 1.x 允许你像取得一般的Javabeans的属性那样直接取得你Action中的所有属性, 属性可以包含丰富的对象类型甚至可以有自己的属性, 而这些属性都可以从Web页面中访问WebWork也支持FormBean模式, 在 "Populate Form Bean and access its value"中,有相关的论述 WebWork 2 拥有WebWork 1相同的特性, 除此之外,还添加了模型驱动(ModelDriven)Action.模型驱动Action允许你把富对象类型或者是域对象当做form bean使用,这样它的属性可以在web页面上直接访问,而不用做为Action的属性的一个子属性来访问.
Expression Language Struts 1.1 集成 JSTL, 因此可以在Struts中使用JSTL EL. 这种EL语言只能进行基本的对象图的遍历,对于集合和索引属性方面的支持要弱一些. WebWork 1.x拥有自己的表达式语言用以访问值堆栈. 对集合以及索引属性的提供很基本的支持但工作的很好.WebWork也能和JSTL一起工作 WebWork 使用Ognl,一个非常强大的表达式语言, 可以访问值堆栈. Ognl 对集合和索引属性提供强有力的支持. Ognl 还拥有其他强大的特性,例如projections (调用集合中所有成员的相同方法,把结果构造成一个新的集合), selections (用一个选择表达式过滤一个集合并返回得到的子集), list construction, and lambda expressions (可以重用的简单函数). Ognl 也可以访问静态方法,静态字段以及类的构造器. WebWork2也能使用JSTL, 参见Using JSTL seamlessly with WebWork
Binding values into views Struts采用标准的JSP机制来把对象绑定到页面(page context),这使得视图与formBean紧密耦合 WebWork 使用可以被WebWork的标签库直接访问的值堆栈, 显得更加灵活并且不会把视图和你要生成的类型绑定起来.这样就可以在很大的范围内复用视图. 同WebWork 1.x
Type Conversion Struts FormBeans 的属性通常都是String类型的. Struts使用Commons-Beanutils进行类型转换.每个类使用一个转换器, 但不允许为每个实例配置不同的转换器. 所以很难得到一个有意义的类型转换错误并把它显示给用户. WebWork 1.x应用 PropertyEditors来进行类型转换. PropertyEditors针对类型而不是Action, 但是字段的错误信息会被加进Action中的字段错误表(field error map)中,并且自动的显示给用户. WebWork2 应用Ognl 进行类型转换,Ognl提供针对基本类型的转换器. 类型转换缺省情况下使用上述转换器, 但也可以为每个类的每个字段指定转换器. 类型转换有默认的错误消息,但是也可以应用WW2的本地化机制来为每个类的每个字段设置一个错误消息.这些消息会被装载到Action的字段错误消息中.
Modular Before & After Processing 必须创建一个继承基类Action的类来作为Action前/后处理的代理, 这会导致类继承层次过深和对多重继承的限制 Comparison to Struts#1 类层次 WebWork 2 允许你在拦截器里面模块化这种处理.拦截器可以通过配置动态的使用而无需和Action类产生耦合.
Validation Struts调用FormBean中的validate()方法,Struts的使用者一般使用Commons Validation来进行验证.我对此不太了解, 因此仅提出几个问题:

由于FormBean的属性一般是String类型的,某些校验方法是否会重复或无法做到?

Commons Validation是否能为同一个类设置不同的校验环境?(我已被告知可以做到, 这是好事)
Commons Validation能否使用为对象属性类定义的校验方式对子对象(sub-objects)进行校验?
WebWork1.x 调用Action中的validate()方法, 即可以手工编写验证也可以调用外部的验证框架(这显然和Struts相同) WebWork2可以使用类似与WebWork和Struts那样使用validate()方法来进行验证,也可以使用这样一个由XWork拦截器激活的验证框架. Xwork验证框架允许用XML格式编写校验器,根据不同的上下文增加自定义验证. Xwork验证框架通过拦截器生效因此和Action完全解耦. Xwork验证框架也允许你使用VisitorFieldValidator对子属性进行持续验证,VisitorFieldValidato利用了为类的属性和上下文定义的验证信息.
Control Of Action Execution 就我所知,Struts为你设置好了Action对象,因此你很难去控制执行的顺序. 为了改变执行的顺序我认为你需要写一个自己的Servlet来处理你需要的分派规则 Action工厂(ActionFactory)控制了Action构建和初始化的顺序,但需要编写一个类 在这点上WebWork 2的拦截器堆栈显得特别强大. Action设置的方方面面都被移到了拦截器的实现中(例如从web设置参数,验证等等), 所以你能根据它们执行顺序控制每一个Action. 例如你想在参数从request设置之前用你的IOC框架来配置action或者进行相反的操作, - 也可以使用截取器栈对每个包或每个类进行控制.

参考

脚注

  1. 一些Struts的用户为Struts开发了一套拦截器框架 (http://struts.sourceforge.net/saif/). 但目前还有一些很严重的局限 (不能进行"包围(around)"处理, 子允许前/后处理) 而且也不是Struts项目的一部分
Site running on a free Atlassian Confluence Open Source Project License granted to WebWork China. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.3 Build:#808 May 29, 2007) - Bug/feature request - Contact Administrators