Struts2源码粗略分析四:理解xwork工作原理

xwork举例

上节已经分析过,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

准备xwork.xml

从下面的配置文件我们可以看出,总共有两个Action对象,而第二个是在第一个对象是与第一个Action形成一个Action链。并且两个Action都是用了自定义拦截器TestInterceptor。

<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 2.0//EN" "http://www.opensymphony.com/xwork/xwork-2.0.dtd"> <xwork> <include file="xwork-default.xml" /> <package name="default" extends="xwork-default" namespace="/test"> <result-types> <result-type name="successResult" class="demo.SuccessResult" /> <result-type name="failedResult" class="demo.FailedResult" /> </result-types> <interceptors> <interceptor name="testInterceptor" class="demo.TestInterceptor" /> </interceptors> <action name="testAction" class="demo.TestAction"> <result name="success" type="chain"> <param name="actionName">testChainAction</param> </result> <result name="failed" type="failedResult" /> <interceptor-ref name="params" /> <!--Model Driven--> <interceptor-ref name="modelDriven" /> <interceptor-ref name="defaultStack" /> <interceptor-ref name="testInterceptor" /> </action> <action name="testChainAction" class="demo.TestChainAction"> <result name="success" type="successResult"> <param name="param">Custom Type</param> </result> <result name="failed" type="failedResult" /> <interceptor-ref name="params" /> <interceptor-ref name="modelDriven" /> <interceptor-ref name="defaultStack" /> <interceptor-ref name="testInterceptor" /> </action> </package> <constant name="devMode" value="false" /> </xwork>

xwork-conversion.properties

demo.TestType=demo.TestConverter

在源码根目录准备一个xwork-conversion.properties文件,里面只需要上面一句话即可,这样我们就可以让xwork自动为TestType类型属性应用TestConverter转换器。

TestCase

根据上面说的业务,我们将测试用例分为三个部分,这样更加便于分析结果。

package demo; import java.util.HashMap; import java.util.Map; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.DefaultActionProxyFactory; import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.config.ConfigurationManager; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; public class TestCase extends junit.framework.TestCase { private static final Logger LOG = LoggerFactory.getLogger(TestCase.class); private DefaultActionProxyFactory actionProxyFactory = null; @Override protected void setUp() throws Exception { /* * 1500 以下 testAction Failed Result * 1500-2000 testAction testChainAction SuccessResult * 2000 以上 testAction testChainAction Failed Result */ super.setUp(); ConfigurationManager cm = new ConfigurationManager(); Configuration conf = cm.getConfiguration(); Container containter = conf.getContainer(); actionProxyFactory = new DefaultActionProxyFactory(); actionProxyFactory.setContainer(containter); } public void test500() throws Exception { LOG.info("TestCase.test500 BEGIN"); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("id", "500"); paramMap.put("name", "param 500 name"); Map<String, Object> context = new HashMap<String, Object>(); context.put(ActionContext.PARAMETERS, paramMap); ActionProxy proxy = actionProxyFactory.createActionProxy("/test", "testAction", context); String result = proxy.execute(); result = result == null ? "NULL" : result; TestAction action = (TestAction) proxy.getAction(); LOG.info("Return: " + result.toString() + "," + action.getModel().getName()); LOG.info("TestCase.test500 END"); } public void test1500() throws Exception { LOG.info("TestCase.test1500 BEGIN"); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("id", "1500"); paramMap.put("name", "param 1500 name"); Map<String, Object> context = new HashMap<String, Object>(); context.put(ActionContext.PARAMETERS, paramMap); ActionProxy proxy = actionProxyFactory.createActionProxy("/test", "testAction", context); String result = proxy.execute(); result = result == null ? "NULL" : result; TestAction action = (TestAction) proxy.getAction(); LOG.info("Return: " + result.toString() + "," + action.getModel().getName()); LOG.info("TestCase.test1500 END"); } public void test2500() throws Exception { LOG.info("TestCase.test2500 BEGIN"); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("id", "2500"); paramMap.put("name", "param 2500 name"); Map<String, Object> context = new HashMap<String, Object>(); context.put(ActionContext.PARAMETERS, paramMap); ActionProxy proxy = actionProxyFactory.createActionProxy("/test", "testAction", context); String result = proxy.execute(); result = result == null ? "NULL" : result; TestAction action = (TestAction) proxy.getAction(); LOG.info("Return: " + result.toString() + "," + action.getModel().getName()); LOG.info("TestCase.test2500 END"); } @Override protected void tearDown() throws Exception { super.tearDown(); } }

运行TestCase并分析日志

以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。

示例源码

FailedResult

package demo; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.Result; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; public class FailedResult implements Result { private static final long serialVersionUID = 7150463892109375313L; private static final Logger LOG = LoggerFactory.getLogger(FailedResult.class); public void execute(ActionInvocation invocation) { LOG.info("FailedResult BEGIN"); Object result = invocation.getStack().findValue("title"); LOG.info(result == null ? "NULL" : result.toString()); LOG.info("FailedResult END"); } }

SuccessResult

package demo; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.Result; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; public class SuccessResult implements Result { private static final long serialVersionUID = -8117508546601266450L; private static final Logger LOG = LoggerFactory.getLogger(SuccessResult.class); private TestType param; public void setParam(TestType param) { this.param = param; } public void execute(ActionInvocation invocation) { LOG.info("SuccessResult BEGIN"); LOG.info(param.getValue()); LOG.info("SuccessResult END"); } }

TestAction

package demo; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.DefaultActionProxy; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; public class TestAction implements Action, ModelDriven<TestModel> { private static final Logger LOG = LoggerFactory.getLogger(DefaultActionProxy.class); private TestModel model = new TestModel(); private int id; private String name; public String execute() throws Exception { try { LOG.info("TestAction BEGIN"); LOG.info(new Integer(id).toString()); LOG.info(name); model.setName("Action Name"); LOG.info("TestAction SUCCESS"); if (id < 1000) return "failed"; return "success"; } catch (Exception e) { LOG.info("TestAction EXCEPTION"); return null; } finally { LOG.info("TestAction END"); } } public TestModel getModel() { return model; } public void setId(int id) { LOG.info("TestAction.setId BEGIN"); this.id = id; LOG.info("TestAction.setId END"); } public void setName(String name) { LOG.info("TestAction.setName BEGIN"); this.name = name; LOG.info("TestAction.setName END"); } }

TestCase

package demo; import java.util.HashMap; import java.util.Map; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.DefaultActionProxyFactory; import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.config.ConfigurationManager; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; public class TestCase extends junit.framework.TestCase { private static final Logger LOG = LoggerFactory.getLogger(TestCase.class); private DefaultActionProxyFactory actionProxyFactory = null; @Override protected void setUp() throws Exception { /* * 1500 以下 testAction Failed Result * 1500-2000 testAction testChainAction SuccessResult * 2000 以上 testAction testChainAction Failed Result */ super.setUp(); ConfigurationManager cm = new ConfigurationManager(); Configuration conf = cm.getConfiguration(); Container containter = conf.getContainer(); actionProxyFactory = new DefaultActionProxyFactory(); actionProxyFactory.setContainer(containter); } public void test500() throws Exception { LOG.info("TestCase.test500 BEGIN"); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("id", "500"); paramMap.put("name", "param 500 name"); Map<String, Object> context = new HashMap<String, Object>(); context.put(ActionContext.PARAMETERS, paramMap); ActionProxy proxy = actionProxyFactory.createActionProxy("/test", "testAction", context); String result = proxy.execute(); result = result == null ? "NULL" : result; TestAction action = (TestAction) proxy.getAction(); LOG.info("Return: " + result.toString() + "," + action.getModel().getName()); LOG.info("TestCase.test500 END"); } public void test1500() throws Exception { LOG.info("TestCase.test1500 BEGIN"); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("id", "1500"); paramMap.put("name", "param 1500 name"); Map<String, Object> context = new HashMap<String, Object>(); context.put(ActionContext.PARAMETERS, paramMap); ActionProxy proxy = actionProxyFactory.createActionProxy("/test", "testAction", context); String result = proxy.execute(); result = result == null ? "NULL" : result; TestAction action = (TestAction) proxy.getAction(); LOG.info("Return: " + result.toString() + "," + action.getModel().getName()); LOG.info("TestCase.test1500 END"); } public void test2500() throws Exception { LOG.info("TestCase.test2500 BEGIN"); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("id", "2500"); paramMap.put("name", "param 2500 name"); Map<String, Object> context = new HashMap<String, Object>(); context.put(ActionContext.PARAMETERS, paramMap); ActionProxy proxy = actionProxyFactory.createActionProxy("/test", "testAction", context); String result = proxy.execute(); result = result == null ? "NULL" : result; TestAction action = (TestAction) proxy.getAction(); LOG.info("Return: " + result.toString() + "," + action.getModel().getName()); LOG.info("TestCase.test2500 END"); } @Override protected void tearDown() throws Exception { super.tearDown(); } }

TestChainAction

package demo; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; public class TestChainAction implements Action, ModelDriven<TestModel> { private static final Logger LOG = LoggerFactory .getLogger(TestChainAction.class); private TestModel model = new TestModel(); private int id; private String name; public String execute() throws Exception { try { LOG.info("TestChainAction BEGIN"); LOG.info(new Integer(id).toString()); LOG.info(name); model.setName("Chain Action Name"); LOG.info("TestChainAction SUCCESS"); if (id < 2000) return "failed"; return "success"; } catch (Exception e) { LOG.info("TestChainAction EXCEPTION"); return null; } finally { LOG.info("TestChainAction END"); } } public TestModel getModel() { return model; } public void setId(int id) { LOG.info("TestChainAction.setId BEGIN"); this.id = id; LOG.info("TestChainAction.setId END"); } public void setName(String name) { LOG.info("TestChainAction.setName BEGIN"); this.name = name; LOG.info("TestChainAction.setName END"); } }

TestConverter

package demo; import java.lang.reflect.Member; import java.util.Map; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; import ognl.DefaultTypeConverter; public class TestConverter extends DefaultTypeConverter { private static final Logger LOG = LoggerFactory.getLogger(TestConverter.class); public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType) { try { LOG.info("TestConverter.convertValue BEGIN"); // context.keySet().toArray() TestChainAction tca = (TestChainAction)context.get("action"); String val = "+ [" + propertyName + "] +----> " + tca.getModel().getName(); LOG.info(val); return new TestType(val); } catch (Exception e) { LOG.info("TestConverter.convertValue EXCEPTION"); return null; } finally { LOG.info("TestConverter.convertValue END"); } } }

TestInterceptor

package demo; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import com.opensymphony.xwork2.interceptor.PreResultListener; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; public class TestInterceptor extends AbstractInterceptor { private static final long serialVersionUID = 1478834996735490593L; private static final Logger LOG = LoggerFactory.getLogger(TestInterceptor.class); public String intercept(ActionInvocation invocation) throws Exception { try { LOG.info("TestInterceptor BEGIN"); invocation.addPreResultListener(new PreResultListener() { private final Logger LOG = LoggerFactory.getLogger(this.getClass()); public void beforeResult(ActionInvocation invocation, String resultCode) { LOG.info("PreResultListener.beforeResult BEGIN"); Object result = invocation.getStack().findValue("title"); LOG.info(result == null ? "NULL" : result.toString()); LOG.info("PreResultListener.beforeResult END"); } }); LOG.info("TestInterceptor SUCCESS"); return invocation.invoke(); } catch (Exception e) { LOG.info("TestInterceptor EXCEPTION"); return null; } finally { LOG.info("TestInterceptor END"); } } }

TestModel

package demo; public class TestModel { String id; String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

TestType

package demo; public class TestType { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public TestType(String value) { this.value = value; } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值