上节已经分析过,Struts2中真正的核心组件是xwork,Struts2对其进行包装,然后将各个关联文信息准备妥当之后就会将任务的调度权转给xwork,xwork会根据配置好的struts.xml来进行任务调度。至于为什么是strust.xml而不是xwork.xml,请参考org.apache.struts2.dispatcher.Dispatcher的init_TraditionalXmlConfigurations方法实现。
在这里我们来看一个纯xwork例子来熟悉xwork的工作原理。
例子中的代码是参考http://www.javaeye.com/topic/57160,并稍作修改而成。
业务逻辑如下:
1500 以下 testAction Failed Result 1500-2000 testAction testChainAction SuccessResult 2000 以上 testAction testChainAction Failed Result
从下面的配置文件我们可以看出,总共有两个Action对象,而第二个是在第一个对象是与第一个Action形成一个Action链。并且两个Action都是用了自定义拦截器TestInterceptor。
demo.TestType=demo.TestConverter
在源码根目录准备一个xwork-conversion.properties文件,里面只需要上面一句话即可,这样我们就可以让xwork自动为TestType类型属性应用TestConverter转换器。
根据上面说的业务,我们将测试用例分为三个部分,这样更加便于分析结果。
以JUnit形式运行我们的TestCase,可以得到以下三部分输出内容,分别对应三个测试方法,这里我们只针对第三种输出做一下详细的分析。
Nov 30, 2010 7:37:50 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Parsing configuration file [xwork.xml]
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestCase.test500 BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setId BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setId END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setName BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setName END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor SUCCESS
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: 500
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: param 500 name
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction SUCCESS
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: NULL
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: FailedResult BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: NULL
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: FailedResult END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Return: failed,Action Name
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestCase.test500 END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Parsing configuration file [xwork.xml]
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestCase.test1500 BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setId BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setId END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setName BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setName END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor SUCCESS
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: 1500
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: param 1500 name
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction SUCCESS
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: NULL
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction.setId BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction.setId END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction.setName BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction.setName END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor SUCCESS
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: 1500
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: param 1500 name
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction SUCCESS
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: NULL
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: FailedResult BEGIN
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: NULL
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: FailedResult END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Return: success,Action Name
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestCase.test1500 END
Nov 30, 2010 7:37:51 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Parsing configuration file [xwork.xml]
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestCase.test2500 BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setId BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setId END
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setName BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction.setName END
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor SUCCESS
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: 2500
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: param 2500 name
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction SUCCESS
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestAction END
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: NULL
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult END
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction.setId BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction.setId END
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction.setName BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction.setName END
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor SUCCESS
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: 2500
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: param 2500 name
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction SUCCESS
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestChainAction END
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult BEGIN
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: NULL
Nov 30, 2010 7:57:57 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: PreResultListener.beforeResult END
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestConverter.convertValue BEGIN
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: + [param] +----> Chain Action Name
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestConverter.convertValue END
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: SuccessResult BEGIN
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: + [param] +----> Chain Action Name
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: SuccessResult END
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor END
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestInterceptor END
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Return: success,Action Name
Nov 30, 2010 7:58:00 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: TestCase.test2500 END
大部分的日志内容都是成对儿出现的(BEGIN和END),首先是TestCase.test2500,测试三启动;TestAction.setId和TestAction.setName,为被调用的Action设置参数值;TestInterceptor,自定义的拦截器被启动;TestAction被启动,并从中输出测试内容;结果监听器PreResultListener被启动;有是先赋值(setId、setName),然后TestChainAction被启动;PreResultListener被启动,紧跟着就是TestConverter.convertValue进行类型转换,最后从类SuccessResult得到这个处理后的结果数据;拦截器TestInterceptor调用结束,最终再次返回TestCase.test2500。