`
jamesby
  • 浏览: 383931 次
  • 性别: 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  
你说的很有道理

相关推荐

    struts2.0入门

    这个“struts2.0入门”压缩包很可能是为了帮助初学者快速掌握Struts2.0的基础知识和核心概念。下面将详细阐述Struts2.0的一些关键知识点。 1. **Struts2框架介绍**:Struts2是Apache软件基金会的开源项目,是Struts...

    struts2.0一个简单的入门实例

    以下是一个简单的入门实例,帮助初学者理解如何配置和使用Struts2.0。 首先,我们需要创建一个新的Web项目。在MyEclipse中,你可以新建一个Web项目,例如命名为"Struts2入门实例"。接下来,你需要导入Struts2运行所...

    struts2_入门实例

    在本入门实例中,我们将探讨如何使用Struts2创建一个简单的Web应用程序。 首先,我们需要确保具备正确的开发环境。在本教程中,使用的是MyEclipse6作为开发工具,Tomcat6作为Web服务器,Struts2的版本为2.0.11.1,...

    struts2入门实例教程详解

    ### Struts2入门实例教程详解 #### 一、环境搭建与基本配置 在开始学习Struts2框架之前,首先需要确保开发环境的正确搭建。根据提供的文档,所使用的开发工具为MyEclipse6,Web服务器为Tomcat6,Struts版本为...

    Struts2的第一个入门实例(一)

    这个入门实例展示了Struts2的基本工作流程:用户请求被Struts2过滤器捕获,然后转发到对应的Action执行业务逻辑,Action返回的结果再由Struts2渲染到指定的JSP页面。通过这个实例,我们可以开始深入学习Struts2的...

    struts2实例入门教程

    在`XML`配置中添加URI类型的关键字,指向`struts-2.0.dtd`,以解决MyEclipse默认不支持Struts2的问题。 5. **快捷键设置**: - 如果在MyEclipse 6.5中,`Ctrl+Space`与输入法切换冲突,可以调整快捷键设置,比如...

    (2.0版本)自己写的struts2+hibernate+spring实例

    该项目使用的jar包为以下. spring-beans.jar xwork-2.0.4.jar spring-context.jar ognl-2.6.11.jar spring-web.jar spring-core.jar struts2-core-2.0.11.1.jar commons-logging-...

    struts简单实例详解

    以上就是一个简单的Struts2入门实例。通过这个例子,你可以了解到Struts如何处理用户请求,如何组织Action和Result,以及如何与视图进行交互。随着对Struts框架的深入学习,你可以掌握更多高级特性,如拦截器、国际...

    非常好的struts2入门资料

    它基于Apache Software Foundation的XWork库,并且在Java社区中被广泛使用,尤其适合初学者入门。 首先,要开始学习Struts2,你需要准备一些基本的环境。这包括下载Struts2的核心包,例如`struts-2.1.6-all.zip`。...

    【张冰Struts2学习笔记】0102_第一个Struts2实例

    这篇学习笔记将带你入门Struts2,通过创建第一个实例来理解其核心概念和基本配置。 首先,了解Struts2框架的结构至关重要。Struts2的核心组件包括Action、Result、Interceptor等,它们协同工作,处理HTTP请求并呈现...

    WebWork2开发指南

    - **版本演变**:WebWork最初的设计较为紧凑,但随着需求的增长和技术的进步,WebWork 2.0以后进行了重大的架构调整,主要分为两大部分:WebWork与XWork。其中,WebWork负责处理Web层逻辑,而XWork则专注于处理业务...

    struts2文档

    - **xwork-2.1.2.jar**: XWork类库是Struts2的基础,Struts2是在XWork之上构建的。 - **commons-fileupload-1.2.1.jar**: 文件上传组件,自2.1.6版本起成为必需的JAR包,其中包含的`RequestContext`类对于框架正常...

    WebWork_开发指南

    但从 2.0 版本开始,WebWork 被拆分为 Webwork2 和 XWork 两部分,这一改动极大地提升了框架的灵活性和可扩展性。 #### 二、QuickStart 快速入门 - **准备工作**:快速入门的第一步是下载 WebWork2 的最新版本。在...

    Struts2完美教程

    #### 一、准备工作及实例 **1. 解压struts-2.1.6-all.zip** - **Apps目录**:包含Struts2自带的一些示例程序,可以帮助开发者快速了解Struts2的基本用法。 - **Docs目录**:存放官方文档,对于学习Struts2框架的...

    struts学习笔记

    - **第三方依赖**:commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar、commons-logging-1.0.4.jar、xwork-2.1.2.jar、ognl-2.6.11.jar、freemarker-2.3.13.jar - **获取配置文件**:struts.xml,需放置于项目的...

Global site tag (gtag.js) - Google Analytics