1、 一个拦截器就是在xwork.xml文件中定义的一个无状态Java类,它至少要实现XWork的com.opensymphony.xwork.interceptor.Interceptor接口。代码如下:
public interface Interceptor extends Serializable {
void destroy();
void init();
String intercept(ActionInvocation invocation) throws Exception;
}
2、 实现Interceptor接口的拦截器,代码部分在intercept方法中实现。在intercept方法中,可以直接返回一个Result字符串,这样整个执行直接“短路”,这时Action的execute方法也不会执行(一般很少会这么用)。所以,一般都会在这个方法里调用参数对象invocation的invoke方法,并返回这个方法执行的结果。这样会持续执行后面的拦截器方法以及Action的execute方法等。
3、 大部分的时候,拦截器直接继承WebWork的抽象类com.opensymphony.xwork.interceptor.AroundInterceptor就可以了。这时,需要实现它的before和after方法。Before方法会在Action执行之前调用,after方法在Action执行之后调用。
4、 拦截器的执行顺序。我们可将多个拦截器放一起组装成一个拦截器栈。这样拦截器会按照栈的顺序由上而下执行before方法,所有before方法执行结束,再执行Action的方法,执行Result的方法,再返回执行结果,最后再从下而上执行拦截器的after方法。
5、 拦截器的过滤功能。我们通常会在应用中使用一个通用的定义多个拦截器的拦截器栈。但有些Action方法在调用的时候,不需要要其中的部分拦截器。这时,我们就可以使用拦截器过滤功能。如果拦截器要拥有过滤功能,必须实现抽象类com.opensymphony.xwork.interceptor.MethodFilterInterceptor。这样,拦截器在定义的时候或者在Action引用拦截器栈的时候,我们就可以指定哪些Action方法是需要过滤的,哪些Action是不需要过滤的。
WebWork提供的拦截器介绍
1、 自动为Action设置Http请求数据的拦截器(Parameters Interceptor)。这个拦截器非常方便实用,但完全自动组装对象数据,很可能会带来安全问题。如果Action不需要设置数据,那么这个Action只要实现com.opensymphony.xwork.interceptor.NoParameters接口即可。如果是Action中部分数据需要自动设置,部分数据不允许设置,这样可以实现接口com.opensymphony.xwork.interceptor.ParameterNameAware,可以在这个接口的acceptableParameterName(String parameterName)方法中,定义我们可以接受哪些方法,如果允许只要让这个方法返回True就可以了。
2、 过虑参数功能的拦截器(Parameter Filter Interceptor)。它可以全局阻止非法或不允许Action访问的参数。可以很好的和上面的组装参数的拦截器一起使用。
3、 为Action设置静态数据的拦截器(Static Parameters Interceptor)。它可以将Action定义的静态<param/>参数,设置到Action中。
4、 数据验证拦截器(Validation Interceptor)。定义之后,会调用验证文件或实现验证接口com.opensymphony.xwork.Validateable的所有验证。
5、 验证流程处理拦截器(Workflow Interceptor)。它和上面的拦截器一起使用,处理验证的流程。如果验证通过则继续前进,如果发现有验证错误消息,直接转到Action中定义的输入结果(input)页面。
6、 类型转换错误处理拦截器()。它首先去取得类型转换的错误消息(主要是由设置Http请求参数的拦截器产生),如果取到错误消息,它会将错误消息传递给实现接口com.opensymphony.xwork.ValidationAware的Action,这样我们可以将这些错误消息暴露到页面中。
7、 Action链拦截器(Chaining Interceptor)。它是用来拷贝前一个Action的属性数据到当前Action中。它要求前一个Action必须是chain Result(<result type="chain">),这样才能进行Action的数据拷贝。
8、 防止页面重复提交(或页面重复刷新)拦截器。Token Interceptor和Token Session Interceptor都是防止重复提交的拦截器。不同点是后者在Session存贮了最近一次请求的结果数据。
9、 文件上传的拦截器(File Upload Interceptor)。实现文件上传的功能。如果有人曾经手工写过文件上传程序,那一定会惊叹于这个拦截器。我们可以在这个拦截器中设定上传文件的大小和类型限制。记得需要第三方的文件上传库的支持,只要在webwork.properties中配置过,并拷贝相应的jar包就可以了。
10、 进度条等待拦截器(Execute and Wait Interceptor)。当Action的执行需要很长实际的时候,我们可以使用这个进度条等待的拦截器。它会将Action放到后台执行,而在前端显示进度条或等待消息提示的页面。
11、 还有一些其它不常用的拦截器,我们可以在WebWork文档中找到,这里就不再做介绍。
IoC 容器
关于IoC容器的描述:
1、 它是一个容器。用来处理不同对象之间的依赖,组装不同的程序元素。
2、 IoC全名是Inversion of Control,即依赖反转控制。它是一种设计模式,IoC容器就是基于这个模式的实现。
3、 有一个比IoC更适合用来命名这一原理的名词,它叫Dependency Injection,即依赖注入。
4、 有了依赖注入,我们可以将IoC容器简单理解为:它是一个用来为对象组装其依赖的对象的容器;也就是说对象本身不用关心它依赖的对象(可以是组件或者服务,反正就是提供业务方法的对象)的创建,初始化,生命周期等,而是由容器来控制。
5、 关于IoC的更多信息可以查看Martin Fowler的经典文章《IoC 容器和Dependency Injection 模式》
WebWork框架本身就提供了一个基于接口的IoC容器。同时WebWork框架和提供了和第三方IoC容器的集成。在WebWork的项目中,我们可以直接使用Spring框架和Pico框架作为自己的IoC容器。而且Spring是WebWork官方推荐的IoC容器。
下面我们将介绍如何使用Spring作为WebWork的IoC容器。在讨论如何集成Spring之前,我们要讨论一个非常有意义的架构问题:
WebWork的Action类是否需要由Spring管理?
1、 否。这样Action类还是象以前那样在xwork文件中定义,我们可以通过标签<external-ref/>定义Action所依赖的Bean组件,或者根据Bean的名字或类型进行自动注入。
2、 是。Action类本身也是有Spring来管理。在xwork定义文件中的Action class就是对Bean的引用,具体的类在Spring的Bean配置文件中定义。这样可以更好的使用Sping为我们提供的更多功能,例如:Spring的复杂AOP功能,基于Acegi的权限控制,等等。
两种方法,根据需要选择一种,我个人更倾向后者。下面我们介绍一下Spring容器的安装步骤:
1、 拷贝Spring依赖的所有jar文件
2、 在web.xml文件定义和开启Spring的监听器,代码如下:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
3、 在webwork.properties中设置WebWork对Spring的支持:webwork.objectFactory = spring
4、 可以在webwork.properties中设置Bean组件的默认组装方式,默认是按照Bean的名称,可以选择按照类型、构造函数、自动选择等方式。
WebWork 原理
WebWork的网站上提供了一个完整的WebWork架构图。它描述了从客户端的一次请求到最后服务器端响应的的整个执行过程。架构图如下:
此架构图一个分为五个部分,其中五个部分分别有五中不同颜色表示。
1、 浅灰色方框。分别代表了客户端的一次Http请求,和服务器端运算结束之后的一次响应。
2、 浅红色方框。表示一次Action请求所要经过的Servlet filters(Servlet 过滤器)。我们可以看到最后一个filter就是我们前面介绍的WebWork的前端控制器。
3、 蓝色方框。这是WebWork框架的核心部分。
1) 一次请求到了WebWork的前端控制器,它首先会根据请求的URL解析出对应的action 名称,然后去咨询ActionMapper这个action是否需要被执行。
2) 如果ActionMapper决定这个action需要被执行,前端控制器就把工作委派给ActionProxy。接着她们会咨询WebWork的配置管理器,并读取在web.xml文件中定义的配置信息。接下来ActionProxy会创建ActionInvocation对象。
3) ActionInvocation是Xwork原理的(Command模式)实现部分。它会调用这个Action已定义的拦截器(before方法),Action方法,Result方法。
4) 最后,看上面流程的图的方向,它会再执行拦截器(after方法),再回到Servlet Filter部分,最后结束并传给用户一个结果响应。
4、 靛色方框。这是拦截器部分,在上面的拦截器章节我们已经有了详细的介绍。
5、 黄色方框。这是我们在开发Web应用时,需要自己开发的程序。其中包括:Action类,页面模板,配置文件xwork.xml。
WebWork 实战和技巧
限于篇幅,我们无法在本章节给出很多详尽的具体实例。其实,在WebWork的代码包中,有一个非常好的演示项目——showcase,它用例子演示了WebWork的几乎所有特性。值得初学的朋友反复研究。我们在本章节中会截取其中的部分代码脚本。
1、 多视图支持。WebWork框架天生支持多种视图技术,包括:Jsp、FreeMarker、Velocity、Jasper Reports、XSLT,还有其它的视图技术。这将在敏捷项目中特别有用。在我咨询的项目中,就有一个因为技术的原因,视图技术由最先的Jsp改为Velocity,后来又改造为FreeMarker。其中,Action类以及后台的程序没有做任何的改动。如果您需要一个视图展现层技术,我在这会好不犹豫的向您推荐FreeMarker。这也是官方的推荐。
关于视图技术的使用,首先是搭建视图技术运行的环境。然后就是编写页面脚本,最后就是在xwork.xml文件中配置。Xwork配置文件中,Result的type参数,就是用来标示所使用的视图技术。在showcase项目中,使用到的视图技术有:Jsp、FreeMarker、Velocity、Jasper Reports。
2、 Action的数据验证功能。在WebWork中,可以在三处实现数据验证功能。一、验证文件(例如:ActionClass-validation.xml文件)中定义数据验证规则。二、在Action中实现com.opensymphony.xwork.Validateable接口的validate方法。三、在Action的执行方法中,硬编码实现验证功能。当然,在实现验证时,我们尽可能的用前面两中方法。
关于验证的说明:
1)、第一种验证需要“validation”拦截器的支持。并可以从任意层次绑定验证文件,可以为一个Action类绑定一个验证文件,也可以为一个具体在xwork.xml文件中的Action定义绑定一个验证文件,可以为Action的一个属性对象绑定一个验证文件,甚至可以为Action的父类绑定验证文件。
2)、WebWork为验证文件提供了一些标准的验证实现:例如:字段必须填写,整型、E-mail地址等等。我们也可以使用表达式语言实现更复杂的数据验证。
3、 类型转换。前面外面一直提到过,WebWork会自动从请求的字符串参数中组装Action需要的数据对象。这样,就会存在一个类型转换的问题。如果Action的字段是基本类型或是一个数据对象,WebWork会自动帮我们处理。如果Action的字段是一个集合,或者我们需要特定的类型转换,这时,我们可以在类型转换的定义文件(ClassName-conversion.properties)中定义转换规则。
4、 一个Action的多个执行方法。WebWork的Action是基于Command模式的实现,在WebWork中,除了实现Action接口的execute()方法之外,Action还可以定义多个执行方法。这些方法必须要是无方法参数,并且返回返回字符串的方法。这样我们在Url中可以用类似下面的格式访问:actionName!methodName.action,例如user!doAdd.action,调用user Action类的doAdd方法。在最新的WebWork中,Action类甚至可以不实现Action接口。
5、 Action链(Action Chaining)。在WebWork中,一次用户请求,可由多个Action共同完成。每个Action可以只实现自己本身的功能单元,这样我们可以根据业务需要为用户的一次请求选择一个或多个Action功能单元来实现。在这样的多个Action之间可以通过chain拦截器共享数据。如果请求由Action x 链到Action y,如果这时y需要获得x的数据,我们就需要为Action y添加chain拦截器。
例如:在showcase中就由Action Chaining的应用。它将Action“actionChain2”链到另外一个Action“actionChain3”,配置文件代码如下:
< action name = "actionChain2" class = "com.opensymphony.webwork.showcase.actionchaining.ActionChain2" >
< result type = "chain" > actionChain3 </ result >
</ action >
< action name = "actionChain3" class = "com.opensymphony.webwork.showcase.actionchaining.ActionChain3" >
< result > /actionchaining/actionChainingResult.jsp </ result >
</ action >
注意:如果要加 chain 拦截器,是需要加到 actionChain3 中,而不是 actionChain2 。
6、 多模块支持解决方案。 WebWork 提供了很灵活的多模块解决方案,这样我们可以很好的组织复杂的 Web 应用项目。
1 )可以在 xwork.xml 文件中,用 include 标签包含另外的一个 xwork 配置文件。例如: <include file="webwork-default.xml"/>
2 ) xwork.xml 配置文件支持 package 。我们可以将一个业务模块的定义方到一个 package , package 支持继承功能,子 package 可以享有父 package 的所有定义。
3 )可以为 package 定义一个命名空间。不同的命名空间可以定义相同的 action 名字。命名空间会用于访问 action 的 URL ,基于这个命名空间,我们可以实现资源权限的访问控制。
7、 doInput 方法。这是我们常用的小技巧,有时候请求的就是一个页面模板,总不能为这个单独写一个 Action 类吧,这时我们就可以用 ActionSupport 的 doInput 方法,直接返回在 Actoion 中定义为“ input ”的 result 。
8、 prepare方法。如果在Action执行之前,必须要初始化一些数据。我们可以将这些初始化的代码方到prepare方法中。这时,Action类要实现接口com.opensymphony.xwork.Preparable,同时这个Action的定义还需要PrepareInterceptor拦截器的支持。
9、 Action的Model Driven。我们大部分的时候用得都是Action的Field Driven,即直接将Action的字段作为数据模型。Model Driven是专门为这个Action指定一个模型对象,这样有什么好处呢?好处是在表达式语言中少了一个对象名的前缀。例如:前面值堆栈部分关于Employee的例子,要设置雇员名称,我们必须要表达式语言例如:“employee.name”,如果这个数据是有页面输入得到,那么你就必须有一个Input输入框的name为“employee.name”,因为它有关键字符“.”,如果Javascript脚本使用这个输入框的名字,就会有错误。使用Model Driven之后,这个表达式就可以变为“name”,省去了前面的“employee.”。
10、 Quick Start。这是WebWork2.2.2中非常激动人心的特性。它可以象perl或PHP可以快速看到程序运行结果。这样在Web开发时,可以不用编译Java源代码,也不用去做打包和部署,就可以快速看到最新程序的运行结果,提高开发效率。我们可以在WebWork源码解压包的根目录,输入命令:java -jar webwork-2.2.2.jar quickstart:showcase(需要jdk1.5的支持),以Quick Start模式,运行showcase项目。
展望 WebWork 未来
这是很多人非常关心的一个问题。特别是WebWork2.2版本发布之后,官方宣称WebWork框架将要和Struts合并。这让一些WebWork的用户产生了担忧,合并之后,是不是就意味着自己在WebWork这方面技术和经验的积累都已浪费?已使用或即将使用WebWork的项目是不是就意味着更多的风险?
答案是:完全不用担心这些。WebWork和Struts的合并,是各取所长,然后诞生出一个更加高效的Web框架。而这个框架用得就是WebWork的优秀技术和Struts的强大社区。
合并的情况如下:
1、 产生一个新的项目Struts Action 2.0 = WebWork2.2 + 一些Struts的功能和特性。
2、 WebWork框架将会中止新功能的增加,如果有新的版本发布都会是Bug的修改。
3、 代码、框架的开发者、社区都将移到Struts。
4、 合并的目标是致力于生产率的提高。
5、 Struts不再是一个框架,它是一个社区。
6、 Struts社区中主要有两个Web框架。一个是基于Action模型的Struts Action;另一个是基于组件模型的Struts Shale。
总结
WebWork是本人工具箱中最爱的一个J2EE Web框架。本人开发过单纯使用Jsp和JavaServlet的项目;也曾经自己开发过基于MVC的Web框架;在2002年开始使用Struts开发;后来也在项目中分别使用过Tapestry和Spring MVC Web框架;也在当今的AJAX潮流中随波逐流。上面的一些技术也都非常优秀,擅用他们任何一个都会给您带来很多生产效率的提高。但我仍然是偏爱WebWork。WebWork的与众不同,得力于它基于OGNL的强大的数据存、取方式,得力于它那解耦的拦截器功能,得力于它那无侵入的架构设计。正是由于它,才让Web编程变得更加的自然、简单、灵活、高效。
posted on 2008-06-23 16:18
henry1451 阅读(736)
评论(0) 编辑 收藏 所属分类:
Struts,Webwork,Xwork技术