`
jamesby
  • 浏览: 381027 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

XWork2.0 入门实例代码

阅读更多
Xwork.xml 配置文件

<!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="com.jamesby.xwork.helloworld.SuccessResult" />
			<result-type name="failedResult" class="com.jamesby.xwork.helloworld.FailedResult" />
		</result-types>    
    	<interceptors>
	    	<interceptor name="testInterceptor"  class="com.jamesby.xwork.helloworld.TestInterceptor"/>
	    </interceptors>	
	   <action name="testAction" class="com.jamesby.xwork.helloworld.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="model-driven"/>
			<interceptor-ref name="defaultStack"/>
			
			<interceptor-ref name="testInterceptor"/>			
	   </action>
	   
	   <action name="testChainAction" class="com.jamesby.xwork.helloworld.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="model-driven"/>
			<interceptor-ref name="defaultStack"/>
			<interceptor-ref name="testInterceptor"/>

	   </action>	   
    </package>
    <constant name="devMode" value="false" />
</xwork>


xwork-conversion.properties 属性文件

com.jamesby.xwork.helloworld.TestType=com.jamesby.xwork.helloworld.TestConvert


Action 文件和测试Chain的Action 文件

public class TestAction implements Action, ModelDriven {
	TestModel book = new TestModel();
	int id;
	public String execute() throws Exception {

		System.out.println("\nAction is invoked............");
		System.out.println("Action:Received Id is " + id);
		System.out.println("Action:Receive Book Title is " + book.getTitle());

		// book = bookDAO.findById(id, Book.class);
		book.setTitle("Action Title");
		if (id < 1000)
			return "failed";
		return "success";
	}
	public TestModel getModel() {
		return book;
	}
	public void setId(int id) {
		this.id = id;
	}
}


public class TestChainAction implements Action, ModelDriven {
	TestModel book = new TestModel();
	int id;
	public String execute() throws Exception {

		System.out.println("\nChain Action is invoked............");
		System.out.println("Chain Action:Received Id is " + id);
		System.out.println("Chain Action:Receive Book Title is " + book.getTitle());

		// book = bookDAO.findById(id, Book.class);
		book.setTitle("Chain Action Title");
		if (id < 2000)
			return "success";
		return "failed";
	}
	public TestModel getModel() {
		return book;
	}
	public void setId(int id) {
		this.id = id;
	}
}


ModelDriven 的模型代码

public class TestModel {
	String id;
	String title;
	public void setId(String id) {
		this.id = id;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getId() {
		return this.id;
	}
	public String getTitle() {
		return this.title;
	}
}


Result代码

public class SuccessResult implements Result {
		private TestType param;
		public void setParam(TestType param) {
			this.param = param;
		}
		public void execute(ActionInvocation invocation) {
			System.out.println("\nSuccessResult is invoked..............");
			System.out.println("param is "+param.getValue());
			
			System.out.println("SuccessResult:Received Title is "
					+ invocation.getStack().findValue("title"));
		}
}


public class FailedResult implements Result {
	public void execute(ActionInvocation invocation) {
		System.out.println("\nFailedResult is invoked..............");
		System.out.println("FailedResult:Received Title is "
				+ invocation.getStack().findValue("title"));

	}
}


TypeConvert 文件代码

import java.lang.reflect.Member;
import java.util.Map;

import ognl.DefaultTypeConverter;

public class TestConvert extends DefaultTypeConverter {
	public Object convertValue(Map context, Object target, Member member,
			String propertyName, Object value, Class toType) {
		return new TestType("" + value);
	}
}


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;
	}
}


自定义Interceptor 和 PreResultListener

public class TestInterceptor extends AbstractInterceptor {
	public String intercept(ActionInvocation invocation) throws Exception {
		invocation.addPreResultListener(new PreResultListener() {
			public void beforeResult(ActionInvocation invocation,
					String resultCode) {
				System.out.println("\nPre Result Listerer is invoked........");
				
			}
		});
		return invocation.invoke();
	}
}


Main应用程序代码

public class HelloWorldMain {

	public static void main(String[] args) throws Exception {
		Map paramMap = new HashMap();
		/**
		 * 1000 以下 testAction Failed Result
		 * 1000-2000 testAction testChainAction SuccessResult
		 * 2000 以上 testAction testChainAction Failed Result
		 */
		paramMap.put("id", "500");
		paramMap.put("title", "param title");

		Map context = new HashMap();
		context.put(ActionContext.PARAMETERS, paramMap);

		ConfigurationManager cm = new ConfigurationManager();
		Configuration conf = cm.getConfiguration();
		Container containter = conf.getContainer();
		DefaultActionProxyFactory actionProxyFactory = new DefaultActionProxyFactory();
		actionProxyFactory.setContainer(containter);
		ActionProxy proxy = actionProxyFactory.createActionProxy("/test",
				"testAction", context);
		String result = proxy.execute();
		if ("success".equals(result)) {
			TestAction action = (TestAction) proxy.getAction();
			System.out.println("\nReturn Success.................");
			System.out.println("Return:Return Title is "+action.getModel().getTitle());
		}
		if ("failed".equals(result))
		{
			TestAction action = (TestAction) proxy.getAction();
			System.out.println("\nReturn Failed.................");
			System.out.println("Return:Return Title is "+action.getModel().getTitle());			
		}
	}
}


刚刚学习Xwork2,本来想学struts2 发现需要xwork基础,个人认为学习xwork一是理解它的拦截器机制,二是理解它的ValueStack机制,准备写个xwork2学习小结,希望大家多指点。
分享到:
评论
11 楼 beaner 2007-08-28  
急,我现在遇到一个问题,JDK是1.4的,不知能否使用xwork2
10 楼 jamesby 2007-03-15  
sun_cat 写道
ParametersInterceptor 扩展了抽象类AroundInterceptor。并在其预处理方法
(before)中实现了数据的转换。
数据转换的过程并不复杂:
⑴ 首先由ActionContext获得Map型的参数集parameters。
⑵ 由ActionContext获得值栈(OgnlValueStack)。
⑶ 遍历parameters中的各项数据。
⑷ 通过OgnlValueStack,根据数据的键值,为Model 对象填充属性数据。


public class ParametersInterceptor extends AbstractInterceptor {
}



public abstract class AbstractInterceptor implements Interceptor {
}
没有你说的AroundInterceptor,可能版本不一致,看了container部分代码,哎5.0的新特性,annocation,泛型,枚举不是很熟悉!

一直用1.4版本,目前在补习中.
9 楼 sun_cat 2007-03-15  
ParametersInterceptor 扩展了抽象类AroundInterceptor。并在其预处理方法
(before)中实现了数据的转换。
数据转换的过程并不复杂:
⑴ 首先由ActionContext获得Map型的参数集parameters。
⑵ 由ActionContext获得值栈(OgnlValueStack)。
⑶ 遍历parameters中的各项数据。
⑷ 通过OgnlValueStack,根据数据的键值,为Model 对象填充属性数据。
8 楼 shaucle 2007-03-06  
...
俺指的debug不是print log
而是设断点然后step看值...
7 楼 jamesby 2007-03-05  
debug 结果如下,没有任何新的发现

2007-03-05 18:19:29,484 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loading action configurations from: xwork.xml
2007-03-05 18:19:29,859 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loading action configurations from: xwork-default.xml
2007-03-05 18:19:29,953 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded action configuration from: xwork-default.xml
2007-03-05 18:19:29,953 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded action configuration from: xwork.xml
2007-03-05 18:19:29,953 INFO [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Parsing configuration file [xwork.xml]
2007-03-05 18:19:30,000 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded type: name:default impl:com.opensymphony.xwork2.ObjectFactory
2007-03-05 18:19:30,031 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded type:com.opensymphony.xwork2.ActionProxyFactory name:default impl:com.opensymphony.xwork2.DefaultActionProxyFactory
2007-03-05 18:19:30,046 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded type:com.opensymphony.xwork2.util.ObjectTypeDeterminer name:default impl:com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer
2007-03-05 18:19:30,078 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded type:com.opensymphony.xwork2.util.ObjectTypeDeterminer name:xwork1 impl:com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer
2007-03-05 18:19:30,093 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded type:com.opensymphony.xwork2.util.XWorkConverter name:xwork1 impl:com.opensymphony.xwork2.util.XWorkConverter
2007-03-05 18:19:30,093 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded type:com.opensymphony.xwork2.util.XWorkConverter name:default impl:com.opensymphony.xwork2.util.AnnotationXWorkConverter
2007-03-05 18:19:30,500 INFO [com.opensymphony.xwork2.util.ObjectTypeDeterminerFactory] - Detected GenericsObjectTypeDeterminer, initializing it...
2007-03-05 18:19:30,500 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - processing conversion file [xwork-conversion.properties]
2007-03-05 18:19:30,515 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - 	com.jamesby.xwork.helloworld.TestType:com.jamesby.xwork.helloworld.TestConvert [treated as TypeConverter com.jamesby.xwork.helloworld.TestConvert@64dc11]
2007-03-05 18:19:30,515 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - processing conversion file [xwork-conversion.properties]
2007-03-05 18:19:30,515 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - 	com.jamesby.xwork.helloworld.TestType:com.jamesby.xwork.helloworld.TestConvert [treated as TypeConverter com.jamesby.xwork.helloworld.TestConvert@1ac1fe4]
2007-03-05 18:19:30,515 INFO [com.opensymphony.xwork2.util.XWorkConverter] - Detected AnnotationXWorkConverter, initializing it...
2007-03-05 18:19:30,656 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - processing conversion file [xwork-conversion.properties]
2007-03-05 18:19:30,656 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - 	com.jamesby.xwork.helloworld.TestType:com.jamesby.xwork.helloworld.TestConvert [treated as TypeConverter com.jamesby.xwork.helloworld.TestConvert@18385e3]
2007-03-05 18:19:30,656 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - processing conversion file [xwork-conversion.properties]
2007-03-05 18:19:30,656 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - 	com.jamesby.xwork.helloworld.TestType:com.jamesby.xwork.helloworld.TestConvert [treated as TypeConverter com.jamesby.xwork.helloworld.TestConvert@1cb25f1]
2007-03-05 18:19:30,718 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded {PackageConfig Name:xwork-default namespace: abstract:false parents:[]}
2007-03-05 18:19:30,812 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded {PackageConfig Name:default namespace:/test abstract:false parents:[{PackageConfig Name:xwork-default namespace: abstract:false parents:[]}]}
2007-03-05 18:19:30,859 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded /test/testAction in 'default' package:{ActionConfig com.jamesby.xwork.helloworld.TestAction - action - file:/D:/workspace/xwork/bin/xwork.xml:12:79}
2007-03-05 18:19:30,875 DEBUG [com.opensymphony.xwork2.config.providers.XmlConfigurationProvider] - Loaded /test/testChainAction in 'default' package:{ActionConfig com.jamesby.xwork.helloworld.TestChainAction - action - file:/D:/workspace/xwork/bin/xwork.xml:25:89}
2007-03-05 18:19:30,890 DEBUG [com.opensymphony.xwork2.DefaultActionProxy] - Creating an DefaultActionProxy for namespace /test and action name testAction
2007-03-05 18:19:31,000 DEBUG [com.opensymphony.xwork2.interceptor.ParametersInterceptor] - Setting params title => param titleid => 500
2007-03-05 18:19:31,093 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - Property: id
2007-03-05 18:19:31,093 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - Class: com.jamesby.xwork.helloworld.TestAction
2007-03-05 18:19:31,109 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - converter is null for property id. Mapping size: 0
2007-03-05 18:19:31,109 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - field-level type converter for property [id] = none found
2007-03-05 18:19:31,109 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - global-level type converter for property [id] = none found
2007-03-05 18:19:31,125 DEBUG [com.opensymphony.xwork2.util.XWorkConverter] - falling back to default type converter [com.opensymphony.xwork2.util.XWorkBasicConverter@1507fb2]
2007-03-05 18:19:31,140 ERROR [com.opensymphony.xwork2.interceptor.ParametersInterceptor] - ParametersInterceptor - [setParameters]: Unexpected Exception catched: Error setting expression 'title' with value 'param title'
2007-03-05 18:19:31,140 DEBUG [com.opensymphony.xwork2.interceptor.StaticParametersInterceptor] - Setting static parameters {}
2007-03-05 18:19:31,140 DEBUG [com.opensymphony.xwork2.interceptor.ParametersInterceptor] - Setting params title => param titleid => 500
2007-03-05 18:19:31,156 DEBUG [com.opensymphony.xwork2.DefaultActionInvocation] - Executing action method = null

Action is invoked............
Action:Received Id is 500
Action:Receive Book Title is param title
Action Classes is class com.jamesby.xwork.helloworld.TestAction

Pre Result Listerer is invoked........

FailedResult is invoked..............
FailedResult:Received Title is Action Title

Return Failed.................
Return:Return Title is Action Title


而且在ParameterInterceptor看到的代码如下:

    protected void setParameters(Object action, ValueStack stack, final Map parameters) {
        ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware)
                ? (ParameterNameAware) action : null;

        Map params = null;
        if( ordered ) {
            params = new TreeMap(getOrderedComparator());
            params.putAll(parameters);
        } else {
            params = new TreeMap(parameters); 
        }
        
        for (Iterator iterator = params.entrySet().iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String name = entry.getKey().toString();

            boolean acceptableName = acceptableName(name)
                    && (parameterNameAware == null
                    || parameterNameAware.acceptableParameterName(name));

            if (acceptableName) {
                Object value = entry.getValue();
                try {
                    stack.setValue(name, value);
                } catch (RuntimeException e) {
                    if (devMode) {
                        String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{
                                e.getMessage()
                        });
                        LOG.error(developerNotification);
                        if (action instanceof ValidationAware) {
                            ((ValidationAware) action).addActionMessage(developerNotification);
                        }
                    } else {
                        LOG.error("ParametersInterceptor - [setParameters]: Unexpected Exception catched: " + e.getMessage());
                    }
                }
            }
        }
    }


看到设置属性的代码也就是stack.setValue(name, value),望指点.
6 楼 cngump 2007-03-05  
不错的入门教程。。
5 楼 shaucle 2007-03-05  
可能吧
我记得ActionContext ActionProxy 和ActionInvocation之间的关系有点tricky, 不过思想上就是一个ThreadLocal, 然后你就可以得到里面的任何内容.
忘了其具体怎么初始化的,你可以debug跟踪进去看一下.
4 楼 jamesby 2007-03-05  
shaucle 写道
通过反射很容易做到这一点,而且IOC中用得很多.
如execute方法(不用implements Action),Spring的ware,还有如Seam的@In等

不过WebWork的原码俺没看很多,而且有段时间了,也可能有其它实现方案吧.
我好像没有从代码中看到反射的调用,代码只是对execute进行反射方式的调用。没有对属性的set进行反射调用,才有了上面的猜测!
3 楼 shaucle 2007-03-05  
通过反射很容易做到这一点,而且IOC中用得很多.
如execute方法(不用implements Action),Spring的ware,还有如Seam的@In等

不过WebWork的原码俺没看很多,而且有段时间了,也可能有其它实现方案吧.
2 楼 jamesby 2007-03-04  
对于Xwork怎样传递参数不是很理解,下面说说我目前的理解:

Xwork 核心本身并不负责参数的传递,只是通过ActionContext来实现数据的共享,而ActionContext则是通过ValueStack来实现数据的共享的.

那么数据如何传递给Action,Result 如何使用数据呢?
Result可以通过ActionInvocation获得Action,从而调用ActionInvocation.getAction 的get方法得到数据,也可以通过ActionInvocation直接访问ValueStack取得数据.

而ValueStack的数据是通过 ParametersInterceptor 拦截器实现,拦截器只负责将数据压入ValueStack.

下面是我的问题了,在ParametersInterceptor 并没有看到对Action的set方法的调用.但是Action 确通过设置了ParametersInterceptor 拦截器后,而得到数据,为什么?

我目前唯一的猜测是XWork对Action应用了字结码增强,通过生成子类并在子类的方法中访问ValueStack得到数据.

不知对否?







1 楼 justcode 2007-03-04  
你说的很有道理

相关推荐

Global site tag (gtag.js) - Google Analytics