struts2和struts1的区别
发布网友
发布时间:2022-05-14 18:19
我来回答
共1个回答
热心网友
时间:2022-04-23 11:19
Struts1和Struts2的区别和对比:
Action 类:
• Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口,而struts2的Action是接口。
• Struts 2
Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去
实现 常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。
线程模式:
• Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略*了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
• Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)
Servlet 依赖:
• Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。
• Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2
Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和
HttpServletResponse的必要性。
可测性:
• 测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。
• Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。
捕获输入:
• Struts1
使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经
常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存
在的JavaBean(仍然会导致有冗余的javabean)。
• Struts
2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过
web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种
ModelDriven 特性简化了taglib对POJO输入对象的引用。
表达式语言:
• Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
• Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--"Object Graph Notation Language" (OGNL).
绑定值到页面(view):
• Struts 1使用标准JSP机制把对象绑定到页面中来访问。
• Struts 2 使用 "ValueStack"技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
类型转换:
• Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。
• Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。
校验:
• Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。
• Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性
Action执行的控制:
• Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。
• Struts2支持通过*堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。
一、
引言Struts的第一个版本是在2001年5月份发布的。它的最初设想是通过结合JSP和Servlet,使Web应用的视图和业务/应用逻辑得以清晰
地分离开来。在Struts之前,最常见的做法是在JSP中加入业务和应用逻辑,或者在Servlet中通过println()来生成视图。
自从第一版发布以来,Struts实际上已成为业界公认的Web应用标准。它的炙手可热也为自己带来了改进和变更,所以不但要跟上对Web应用框架
不断变化的需求,而且要与日渐增多竞争激烈的众多框架的特性相融合。到最后,产生了几个下一代Struts的解决方案。其中两个最受瞩目的方案是
Shale和Struts Ti。
Shale是一个基于构件的框架,并在最近成为Apache的顶级项目。而Struts
Ti则是在Struts的成功经验基础上继续坚持对前端控制器(Front
Controller)和MVC(model-view-controller)模式进行改进。WebWork项目是在2002年3月发布的,它对
Struts式框架进行了*性改进,引进了不少新的思想、概念和功能,但和原Struts代码并不兼容。WebWork是一个成熟的框架,经过了好几次
重大的改进与发布。在2005年12月,WebWork与Struts Ti宣布合并。与此同时,Struts
Ti改名为Struts Action Framework
2.0,成为Struts真正的继承者。最后要注意的是,并不是说Struts或WebWork项目已经停止开发了。由于人们对这两个项目的兴趣仍然很
高,而且也有很多开发者仍然愿意使用它们,因此这两个项目还在继续开发中,继续修复Bug,改进功能和继续添加新功能。
二、
Action的区别对于有着丰富的Struts1.x开发经验的朋友来说,都十分的清楚Action是整个Struts框架的核心内容,当然
Struts2也不例外。不过,Struts1.x与Struts2的Action模型很大的区别。Struts2和Struts1.x的差别,最明显的
就是Struts2是一个pull-MVC架构。
这是什么意思呢?从开发者角度看,就是说需要显示给用户的数据可以直接从Action中获取,而不像
Struts1.x那样,必须把相应的Bean存到Page、Request或者Session中才能获取。Struts1.x
必须继承org.apache.struts.action.Action或者其子类,表单数据封装在FormBean中。
Struts
2无须继承任何类型或实现任何接口,表单数据包含在Action中,通过Getter和Setter获取(如下面的ActionForStruts2的代
码示例)。虽然,在理论上Struts2的Action无须实现任何接口或者是继承任何的类,但是,在实际编程过程中,为了更加方便的实现Action,
大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并且重载(Override)此类里的
String execute()方法。
首先,从ActionForStruts2可以看出,返回的对象不是ActionForward,而是String。如果你不喜欢以字符串的形式出
现在你的代码中,有个Helper接口Action可以以常量方式提供常见结果,如“success”、“none”、“error”、“input”和
“login”。
另外,按照惯例,在Struts1.x中只有“execute”方法能调用Action, 但在Struts2中并非必要,任何声明为public String methodName() 方法,都能通过配置来调用Action。
最后,和Struts1.x最大的*性的不同是,Struts2处理Action过程中调用的方法(“execute”方法)是不带参数的。
那如何获取所需要的对象呢?答案是使用IoC(反转控制,Inversion of Control),也叫“依赖注入(Dependency Injection)”的模式(想更多地了解这方面信息请看Martin Fowler的文章http://www.martinfowler.com/articles/injection.html)。Spring框架使得这个模式流行起来,然而Struts2的前身(WebWork)也同时应用上了这个模式。
三、 IoCIoC(Inversion of Control,以下译为控制反转),随着Java社区中轻量级容器(Lightweight
Contianer)的推广而越来越为大家耳熟能详。在此,无需再多费唇舌来解释“什么是控制反转”和“为什么需要控制反转”。因为互联网上已经有非常多
的文章对诸如此类的问题作了精彩而准确的回答。
读者可以去读一下Rod Johnson和Juergen Hoeller合著的《Expert one-on-one J2EE
Development without EJB》或Martin Fowler所写的《Inversion of Control
Containers and the Dependency Injection pattern》。众所周知,Struts2是以Webwork
2作为基础发展出来。而在Webwork 2.2之前的Webwork版本,其自身有一套控制反转的实现,Webwork
2.2在Spring 框架的如火如荼发展的背景下,决定放弃控制反转功能的开发,转由Spring实现。
值得一提的是,Spring确实是一个值得学习的框架,因为有越来越多的开源组件(如iBATIS等)都放弃与Spring重叠的功能的开发。因此,Struts2推荐大家通过Spring实现控制反转。
为了更好地了解反转控制,下面来看一个例子,如何利用IoC在Action处理过程中可以访问到当前请求HttpServerRequest对象。在例子中,使用的依赖注入机制是接口注入。就如其名称一样,接口注入需要的是已经被实现了的接口。
这个接口包含了相应属性的setter,为Action提供值。
例子中使用了ServletRequestAware接口,如下:
public interface ServletRequestAware { public void setServletRequest(HttpServletRequest request);}
当继承这个接口后,原本简单的Action看起来有点复杂了,但是这时可以获取HttpServerRequest对象来使用了。
public class IoCForStruts2 implements ServletRequestAware {
private HttpServletRequest request;
public void setServletRequest(HttpServletRequest request) {
this.request = request; }
public String execute() throws Exception {
// 可以开始使用request对象进行工作了
return Action.SUCCESS; }
}
看起来现在这些属性是类级别的,并不是线程安全的,会出现问题。
其实在Struts2里并没有问题,因为每个请求过来的时候都会产生一个新的Action对象实例,它并没有和其他请求共享一个对象,所以不需要考虑线程安全问题。
* Interceptor(以下译为*),在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
拦截是AOP的一种实现策略。在Webwork的中文文档的解释为——*是动态拦截Action调用的对象。它提供了一种机制可以使开发者定义
在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也提供了一种可以提取action中可重用的部分的方式。
Struts1.x的标准框架中不提供任何形式的*,虽一个名为SAIF的附加项目则实现了这样的功能,但它的适用的范围还很有限。
*是Struts2的一个强有力的工具,有许多功能(feature)都是构建于它之上,如国际化、转换器,校验等。谈到*,还有一个流行
的词——*链(Interceptor Chain,在Struts2中称为*栈Interceptor Stack)。
*链就是将*按一定的顺序联结成一条链。在访问被拦截的方法或字段时,*链中的*就会按其之前定义的顺序被调用。
Struts 2的*实现相对比较简单。当请求到达Struts2的ServletDispatcher时,Struts
2会查找配置文件,并根据其配置实例化相对的*对象,然后串成一个列表(list),最后一一地调用列表中的*,Struts
2已经提供丰富多样功能齐全的*实现。
读者可以到struts2-all-2.0.6.jar或struts2-core-2.0.6.jar包的struts-default.xml
查看关于默认的*与*链的配置。作为“框架(framework)”,可扩展性是不可缺少的,因为世上没有放之四海而皆准的东西。
虽然,Struts 2为我们提供如此丰富的*实现,但是这并不意味我们失去创建自定义*的能力,恰恰相反,在Struts 2自定义*是相当容易的一件事。
前面已经简要介绍了
Struts2的起源,并详细对比了Struts2和Struts1.x的差异,读者应该对Struts2的基础有所了解了——包括高层的框架概念和基础
的请求流程,并理解Struts1.x和Struts2两者之间在Action方面的差别,Struts2加强了对*与IoC的支持,而在
Struts1.x中,这些特性是很难想象的。
同时,读者应该明白: Struts2是WebWork的升级,而不是Struts 1.x的升级。虽然Struts
2提供了与Struts1.x的兼容,但已经不是Struts1.x的升级。对于已有Struts1.x开发经验的开发者而言,Struts1.x的开发
经验对于Struts2并没有太大的帮助;相反,对于已经有WebWork开发经验的开发者而言,WebWork的开发经验对Struts2的开发将有很
好的借鉴意义。