- 浏览: 383449 次
- 性别:
文章分类
最新评论
-
wjw103:
You are using old notation for ...
Struts2 入门实例代码 -
hhb19900618:
你好 你这个工程压缩包是不是有问题啊?根本不能导入?
Struts2 入门实例代码 -
it爱:
[list][*]dsadsa[*]dsadsa[*]dsad ...
Spring AOP 学习小结 -
youjianbo_han_87:
和 weblogic 有个毛线关系???????
Weblogic下的自动任务 -
hua839:
是用SmartUpload进行文件上传
Xwork.xml 配置文件
xwork-conversion.properties 属性文件
Action 文件和测试Chain的Action 文件
ModelDriven 的模型代码
Result代码
TypeConvert 文件代码
自定义Interceptor 和 PreResultListener
Main应用程序代码
刚刚学习Xwork2,本来想学struts2 发现需要xwork基础,个人认为学习xwork一是理解它的拦截器机制,二是理解它的ValueStack机制,准备写个xwork2学习小结,希望大家多指点。
一直用1.4版本,目前在补习中.
<!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 对象填充属性数据。
(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 对象填充属性数据。
(before)中实现了数据的转换。
数据转换的过程并不复杂:
⑴ 首先由ActionContext获得Map型的参数集parameters。
⑵ 由ActionContext获得值栈(OgnlValueStack)。
⑶ 遍历parameters中的各项数据。
⑷ 通过OgnlValueStack,根据数据的键值,为Model 对象填充属性数据。
8 楼
shaucle
2007-03-06
...
俺指的debug不是print log
而是设断点然后step看值...
俺指的debug不是print log
而是设断点然后step看值...
7 楼
jamesby
2007-03-05
debug 结果如下,没有任何新的发现
而且在ParameterInterceptor看到的代码如下:
看到设置属性的代码也就是stack.setValue(name, value),望指点.
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跟踪进去看一下.
我记得ActionContext ActionProxy 和ActionInvocation之间的关系有点tricky, 不过思想上就是一个ThreadLocal, 然后你就可以得到里面的任何内容.
忘了其具体怎么初始化的,你可以debug跟踪进去看一下.
4 楼
jamesby
2007-03-05
shaucle 写道
通过反射很容易做到这一点,而且IOC中用得很多.
如execute方法(不用implements Action),Spring的ware,还有如Seam的@In等
不过WebWork的原码俺没看很多,而且有段时间了,也可能有其它实现方案吧.
我好像没有从代码中看到反射的调用,代码只是对execute进行反射方式的调用。没有对属性的set进行反射调用,才有了上面的猜测!如execute方法(不用implements Action),Spring的ware,还有如Seam的@In等
不过WebWork的原码俺没看很多,而且有段时间了,也可能有其它实现方案吧.
3 楼
shaucle
2007-03-05
通过反射很容易做到这一点,而且IOC中用得很多.
如execute方法(不用implements Action),Spring的ware,还有如Seam的@In等
不过WebWork的原码俺没看很多,而且有段时间了,也可能有其它实现方案吧.
如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得到数据.
不知对否?
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的一些关键知识点。 1. **Struts2框架介绍**:Struts2是Apache软件基金会的开源项目,是Struts...
以下是一个简单的入门实例,帮助初学者理解如何配置和使用Struts2.0。 首先,我们需要创建一个新的Web项目。在MyEclipse中,你可以新建一个Web项目,例如命名为"Struts2入门实例"。接下来,你需要导入Struts2运行所...
在本入门实例中,我们将探讨如何使用Struts2创建一个简单的Web应用程序。 首先,我们需要确保具备正确的开发环境。在本教程中,使用的是MyEclipse6作为开发工具,Tomcat6作为Web服务器,Struts2的版本为2.0.11.1,...
### Struts2入门实例教程详解 #### 一、环境搭建与基本配置 在开始学习Struts2框架之前,首先需要确保开发环境的正确搭建。根据提供的文档,所使用的开发工具为MyEclipse6,Web服务器为Tomcat6,Struts版本为...
这个入门实例展示了Struts2的基本工作流程:用户请求被Struts2过滤器捕获,然后转发到对应的Action执行业务逻辑,Action返回的结果再由Struts2渲染到指定的JSP页面。通过这个实例,我们可以开始深入学习Struts2的...
在`XML`配置中添加URI类型的关键字,指向`struts-2.0.dtd`,以解决MyEclipse默认不支持Struts2的问题。 5. **快捷键设置**: - 如果在MyEclipse 6.5中,`Ctrl+Space`与输入法切换冲突,可以调整快捷键设置,比如...
该项目使用的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-...
以上就是一个简单的Struts2入门实例。通过这个例子,你可以了解到Struts如何处理用户请求,如何组织Action和Result,以及如何与视图进行交互。随着对Struts框架的深入学习,你可以掌握更多高级特性,如拦截器、国际...
这篇学习笔记将带你入门Struts2,通过创建第一个实例来理解其核心概念和基本配置。 首先,了解Struts2框架的结构至关重要。Struts2的核心组件包括Action、Result、Interceptor等,它们协同工作,处理HTTP请求并呈现...
- **版本演变**:WebWork最初的设计较为紧凑,但随着需求的增长和技术的进步,WebWork 2.0以后进行了重大的架构调整,主要分为两大部分:WebWork与XWork。其中,WebWork负责处理Web层逻辑,而XWork则专注于处理业务...
- **第三方依赖**: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,需放置于项目的...