- 浏览: 16726 次
最新评论
1.struts2不是struts1的升级,而是继承的webwork的血统,它吸收了struts1和webwork的优势。
2.首先看下struts1的Action官方注释(struts1.3.8源代码)
[code="java"]/**
* An Action is an adapter between the contents of an
* incoming HTTP request and the corresponding business logic that should be
* executed to process this request. The controller (RequestProcessor) will
* select an appropriate Action for each request, create an instance (if
* necessary), and call the execute method.
*
* Actions must be programmed in a thread-safe manner, because the
* controller will share the same instance for multiple simultaneous requests.
* This means you should design with the following items in mind:
*
*
*
* Instance and static variables MUST NOT be used to store information
* related to the state of a particular request. They MAY be used to share
* global resources across requests for the same action.
*
* Access to other resources (JavaBeans, session variables, etc.) MUST be
* synchronized if those resources require protection. (Generally, however,
* resource classes should be designed to provide their own protection where
* necessary.
*
*
*
* When an Action instance is first created, the controller
* will call setServlet with a non-null argument to identify the
* servlet instance to which this Action is attached. When the servlet is to
* be shut down (or restarted), the setServlet method will be
* called with a null argument, which can be used to clean up any
* allocated resources in use by this Action.
*
* @version $Rev: 471754 $ $Date: 2005-08-26 21:58:39 -0400 (Fri, 26 Aug 2005)
* $
*/
public class Action {
//代码省略。。。。。。。
}
其次,再看下struts2的Action注释(struts2.3.1.2)
[code="java"]package com.opensymphony.xwork2;
/**
* All actions may implement this interface, which exposes the execute() method.
*
* However, as of XWork 1.1, this is not required and is only here to assist users. You are free to create POJOs
* that honor the same contract defined by this interface without actually implementing the interface.
*/
public interface Action {
/**
* The action execution was successful. Show result
* view to the end user.
*/
public static final String SUCCESS = "success";
/**
* The action execution was successful but do not
* show a view. This is useful for actions that are
* handling the view in another fashion like redirect.
*/
public static final String NONE = "none";
/**
* The action execution was a failure.
* Show an error view, possibly asking the
* user to retry entering data.
*/
public static final String ERROR = "error";
/**
* The action execution require more input
* in order to succeed.
* This result is typically used if a form
* handling action has been executed so as
* to provide defaults for a form. The
* form associated with the handler should be
* shown to the end user.
*
* This result is also used if the given input
* params are invalid, meaning the user
* should try providing input again.
*/
public static final String INPUT = "input";
/**
* The action could not execute, since the
* user most was not logged in. The login view
* should be shown.
*/
public static final String LOGIN = "login";
/**
* Where the logic of the action is executed.
*
* @return a string representing the logical result of the execution.
* See constants in this interface for a list of standard result values.
* @throws Exception thrown if a system level exception occurs.
* Note: Application level exceptions should be handled by returning
* an error value, such as Action.ERROR.
*/
public String execute() throws Exception;
}
3.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的开发将有很 好的借鉴意义。
本文源自:http://blog.csdn.net/john2522/article/details/7436307
2.首先看下struts1的Action官方注释(struts1.3.8源代码)
[code="java"]/**
* An Action is an adapter between the contents of an
* incoming HTTP request and the corresponding business logic that should be
* executed to process this request. The controller (RequestProcessor) will
* select an appropriate Action for each request, create an instance (if
* necessary), and call the execute method.
*
* Actions must be programmed in a thread-safe manner, because the
* controller will share the same instance for multiple simultaneous requests.
* This means you should design with the following items in mind:
*
*
*
* Instance and static variables MUST NOT be used to store information
* related to the state of a particular request. They MAY be used to share
* global resources across requests for the same action.
*
* Access to other resources (JavaBeans, session variables, etc.) MUST be
* synchronized if those resources require protection. (Generally, however,
* resource classes should be designed to provide their own protection where
* necessary.
*
*
*
* When an Action instance is first created, the controller
* will call setServlet with a non-null argument to identify the
* servlet instance to which this Action is attached. When the servlet is to
* be shut down (or restarted), the setServlet method will be
* called with a null argument, which can be used to clean up any
* allocated resources in use by this Action.
*
* @version $Rev: 471754 $ $Date: 2005-08-26 21:58:39 -0400 (Fri, 26 Aug 2005)
* $
*/
public class Action {
//代码省略。。。。。。。
}
其次,再看下struts2的Action注释(struts2.3.1.2)
[code="java"]package com.opensymphony.xwork2;
/**
* All actions may implement this interface, which exposes the execute() method.
*
* However, as of XWork 1.1, this is not required and is only here to assist users. You are free to create POJOs
* that honor the same contract defined by this interface without actually implementing the interface.
*/
public interface Action {
/**
* The action execution was successful. Show result
* view to the end user.
*/
public static final String SUCCESS = "success";
/**
* The action execution was successful but do not
* show a view. This is useful for actions that are
* handling the view in another fashion like redirect.
*/
public static final String NONE = "none";
/**
* The action execution was a failure.
* Show an error view, possibly asking the
* user to retry entering data.
*/
public static final String ERROR = "error";
/**
* The action execution require more input
* in order to succeed.
* This result is typically used if a form
* handling action has been executed so as
* to provide defaults for a form. The
* form associated with the handler should be
* shown to the end user.
*
* This result is also used if the given input
* params are invalid, meaning the user
* should try providing input again.
*/
public static final String INPUT = "input";
/**
* The action could not execute, since the
* user most was not logged in. The login view
* should be shown.
*/
public static final String LOGIN = "login";
/**
* Where the logic of the action is executed.
*
* @return a string representing the logical result of the execution.
* See constants in this interface for a list of standard result values.
* @throws Exception thrown if a system level exception occurs.
* Note: Application level exceptions should be handled by returning
* an error value, such as Action.ERROR.
*/
public String execute() throws Exception;
}
3.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的开发将有很 好的借鉴意义。
本文源自:http://blog.csdn.net/john2522/article/details/7436307
发表评论
-
JavaWeb 之 session
2017-10-12 15:06 0一、Session ... -
git clone命令
2017-10-10 15:30 1127git clone 命令参数: usage: gi ... -
Mac下idea快捷键
2017-10-09 17:21 395IntelliJ IDEA For Mac 快捷 ... -
浅谈java中的堆栈(二)
2016-12-16 17:50 0Java 中的堆和栈 Java把内存划分成两种:一种是 ... -
浅谈java中的堆栈(一)
2016-12-16 17:28 310Java把内存分成两种,一种叫做堆内存,一种叫做栈内存:在 ... -
导出excel的两种方式(二)
2015-12-17 15:26 7861.调用类如下: @RequestMapping(&quo ... -
导出excel的两种方式(一)
2015-12-17 15:10 6711.导出excel方法调用: import org.apa ... -
正确选择使用字符串或者数字
2015-12-08 10:53 439在我多年的开发经验中,经常发现的一个情况就是,很多项目的对象 ... -
mybatis在xml文件中处理大于号小于号的方法
2015-06-11 17:30 396第一种方法: 用了转义字符把>和<替换掉,然 ... -
Java中serialVersionUID
2015-06-11 17:31 473serialVersionUID作用: ... -
为什么使用redis
2015-06-11 17:41 473先解释一下软件编程中常见的一些概念: 抽象先于具象。这个抽象 ... -
mybatis入门三之使用MyBatis Generator生成DAO
2015-06-10 18:06 871虽然MyBatis很方便,但是想要手写全部的mapper还是很 ... -
mybatis入门二之添加ehcache缓存支持
2015-06-10 17:57 514为了提高MyBatis的性能, ... -
mybatis入门一
2015-06-10 17:53 329ibatis的3.X版本改名了,叫做MyBatis,暂且不讨论 ... -
spring+mybatis优缺点
2015-06-10 16:43 1611一、mybatis的优缺点: ... -
Java语言滴transient
2015-03-26 21:48 488transient说明一个属性是临时的,不会被序列化。详看事例 ... -
Java语言滴Interface(二)
2015-03-26 21:03 4911.看代码: public interface Anima ... -
Java语言滴Interface
2015-03-26 18:32 4251.相对abstract class(抽象类)来讲,inter ...
相关推荐
sdad
本课程设计是某公司的工资管理系统。在这个计算机快速发展的世界里,计算机为信息处理提供了物美价廉的手段,对于推动我国管理信息处理现代化起到了重要作用。工资管理是一项琐碎、复杂而又十分细致的工作,工资计算、发放、核算的工作量很大,一般不允许出错,如果实行手工操作,每月发放工资须手工填制大量的表格,这就会耗费工作人员大量的时间和精力,计算机进行工资发放工作,不仅能够保证工资核算准确无误、快速输出,而且还可以利用计算机对有关工资的各种信息进行统计,既方便又快捷地完成员工工资的发放。 本课程设计过程中根据设计中的需求及对工资管理系统采用了模块化的设计思想,在机房我们在Windows XP 操作系统环境下,采用 myeclipse7作为开发工具,主要连接 Access 数据库来实现公司的工资管理系统的主要功能。在设计过程中,我们首先小组首先对整体的思路进行分析,然后进行分工。对数据库和类进行设计,实现了工资管理系统的功能。其功能主要包括公司用户管理、人员管理、部门管理、工资管理等功能.。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
基于鸟鸣声识别的鸟类分类系统项目源代码全套技术资料.zip
1、嵌入式物联网单片机项目开发例程,简单、方便、好用,节省开发时间。 2、代码使用IAR软件开发,当前在CC2530上运行,如果是其他型号芯片,请自行移植。 3、软件下载时,请注意接上硬件,并确认烧录器连接正常。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看账号发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件有差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。 9、例程具有一定专业性,非专业人士请谨慎操作。
毕业设计前后端分离博客项目源代码.zip
Eclipse+MySql+JavaSwing选课成绩管理系统,原文博客在https://blog.csdn.net/qq_50062694/article/details/124649345?spm=1001.2014.3001.5502。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
什么是流程挖掘?为什么需要流程挖掘?流程挖掘面向的部门是哪些?流程挖掘之后做什么?如果想知道这些,请阅读此文。
### Android程序开发初级教程(一):初识Android **平台概述** Google推出的Android操作系统平台已经正式亮相,这是一个基于Linux内核的开源操作系统。对于开发者而言,了解其架构和支持的开发语言至关重要。以下是Android平台的架构概览: **平台架构及功能** 1. **应用框架(Application Framework)**:包含可重用和可替换的组件,确保所有软件在该层面上的平等性。 2. **Dalvik虚拟机(Dalvik Virtual Machine)**:一个基于Linux的虚拟机,为Android应用提供运行环境。 3. **集成浏览器(Integrated Browser)**:基于开源WebKit引擎的浏览器,位于应用层。 4. **优化图形(Optimized Graphics)**:包括自定义的2D图形库和遵循OpenGL ES 1.0标准的3D实现。 5. **SQLite数据库**:用于数据存储。 6. **多媒体支持(Media Support)**:支持通用音频、视频以及多种图片格式(如MPEG4, H.264
项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7
212) Outgrid - 多用途 Elementor WordPress 主题 v2.0.0.zip
weixin138社区互助养老+ssm(论文+源码)_kaic.zip
深圳建筑安装公司“高处作业安全技术操作规程”
【项目简介】 代码主干网络采用Swin-Transformer 家族系列,包括【tiny、small、base】三种模型。pretrained和freeze_layers参数为是否采用官方预训练模型和是否仅训练分类头。为了做对比消融试验,优化器采用了Adam和SGD、AdamW三种。损失函数采用多类别的交叉熵、学习率优化策略采用cos余弦退火算法 【评估网络】 评估的指标采用loss和准确率(accuracy),分别会在训练集和验证集上进行评估、输出、绘制曲线图像。同时会在训练集、验证集进行一系列评估,包含混淆矩阵、recall、precision、F1 score等等曲线图像,以及recall、precision、F1 score、特异度的输出信息等等。 【具体各类别的指标在json文件中查看】 【如果想要更换数据集训练,参考readme文件】 【本项目为8种番茄病害图片(约4k张数据),包含数据集和标签,可以一键运行】
城市公交查询功能描述 城市公交查询系统的主要目的是为市民提供便捷的公交信息查询服务,帮助用户快速获取公交线路、站点、时刻表等信息,从而提高出行效率。以下是该系统可能具备的功能描述: 1. 公交线路查询 线路搜索:用户可以通过输入公交线路编号或线路名称,快速查询到该线路的详细信息。 线路详情:展示所选线路的起点、终点、途经站点、首末班车时间、发车间隔等信息。 线路图展示:提供线路的可视化地图,显示线路走向及各个站点位置。 2. 站点查询 站点搜索:用户可以通过输入站点名称或编号,查询该站点的相关信息。 站点详情:展示所选站点的上下车线路、周边设施、换乘信息等。 实时到站信息:提供该站点即将到达的公交车信息,包括预计到达时间和车牌号。 3. 实时公交信息 实时位置追踪:用户可以查看公交车的实时位置,了解公交车的行驶状态。 到站预测:根据实时数据,预测公交车到达各个站点的时间,帮助用户合理安排出行。 4. 换乘查询 换乘方案推荐:用户输入起点和终点后,系统提供最佳的换乘方案,包括所需的公交线路、换乘站点及步行距离。 换乘时间估算:计算并展示换乘所需的总时间,包括等车时间和步行时间。 5.
交通旅游订票功能描述 交通旅游订票系统是为了简化旅游出行过程,提升用户的预定体验。该系统通常集成了机票、火车票、汽车票、船票、景区门票等多种交通和旅游产品的预订、支付及管理功能。以下是该系统可能具备的功能描述: 1. 用户管理 用户注册与登录:提供游客注册与登录功能,支持邮箱、手机号等多种方式注册,保证用户信息安全。 个人信息管理:用户可以查看和编辑个人信息,如身份证号、联系方式、常用地址等。 乘客信息保存:可保存常用乘客信息,如身份证、护照、儿童票信息,方便快速预定。 2. 交通票务管理 票务查询:提供交通工具的实时查询功能,支持机票、火车票、汽车票、船票等的查询,包含出发时间、到达时间、票价、座位情况等信息。 多种票务类型支持:支持单程票、往返票、联程票、团体票等多种票种,满足不同用户需求。 票价比较:根据日期、交通工具等条件,自动比较票价,帮助用户选择最合适的票务。 票务预订与支付:提供便捷的在线预订和支付功能,支持多种支付方式(如银行卡、支付宝、微信等)。 票务改签与退票:用户可以在线申请改签和退票,并查看相关费用及政策。 3. 旅游产品预订 景点门票预订:用户可以在线选择
企业数据管理系统项目源代码.zip
项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7
基于plc的污水处理,组态王动画仿真,带PLC源代码,组态王源代码,图纸,IO地址分配
SINAMICS S120驱动第三方直线永磁同步电机系列视频_配置和优化.mp4