组成Action配置的各个元素,例如 :
1
actions
2
interceptors
3
results
4
package 一 :包的配置
Packages是把
1
Actions
2
Results
3
Result Types
4
Interceptors
5
Stacks 分组成逻辑单元的一种方式,以分享一些共同设置.
包跟对象一样可以扩展,也可以被"子"包覆盖部分属性.

1 : "extends"属性使一个package可以继承一个或多个前面package中的 :
注意,配置文件是被至上而下处理的,所以"被继承"的包必需定义在"继承"包的上面.
2 : "abstract"表示一个包为抽象包
这样的包可以被继承,但是不能有action的定义3 : xwork.xml中包的例子
1
<xwork>
2
3
<include file="webwork-default.xml"/>
4
5
<include file="config-browser.xml"/>
6
7
<include file="xwork-continuations.xml"/>
8
9
<include file="xwork-tags.xml"/>
10
11
<include file="xwork-validation.xml" />
12
13
<include file="xwork-actionchaining.xml" />
14
15
<include file="xwork-ajax.xml" />
16
17
<include file="xwork-fileupload.xml" />
18
19
<include file="xwork-person.xml" />
20
21
<include file="xwork-wait.xml" />
22
23
<include file="xwork-token.xml" />
24
25
<include file="xwork-model-driven.xml" />
26
27
<include file="xwork-filedownload.xml" />
28
29
<package name="default" extends="webwork-default">
30
<interceptors>
31
<interceptor-stack name="crudStack">
32
<interceptor-ref name="params" />
33
<interceptor-ref name="defaultStack" />
34
</interceptor-stack>
35
</interceptors>
36
37
<default-action-ref name="showcase"/>
38
39
<action name="showcase">
40
<result>showcase.jsp</result>
41
</action>
42
43
<action name="date" class="com.opensymphony.webwork.showcase.DateAction">
44
<result name="success">/date.jsp</result>
45
</action>
46
47
</package>
48
49
<package name="skill" extends="default" namespace="/skill">
50
<default-interceptor-ref name="crudStack"/>
51
52
<action name="list" class="com.opensymphony.webwork.showcase.action.SkillAction" method="list">
53
<result>/empmanager/listSkills.jsp</result>
54
<interceptor-ref name="basicStack"/>
55
</action>
56
<action name="edit" class="com.opensymphony.webwork.showcase.action.SkillAction">
57
<result>/empmanager/editSkill.jsp</result>
58
<interceptor-ref name="params" />
59
<interceptor-ref name="basicStack"/>
60
</action>
61
<action name="save" class="com.opensymphony.webwork.showcase.action.SkillAction" method="save">
62
<result name="input">/empmanager/editSkill.jsp</result>
63
<result type="redirect">edit.action?skillName=$
{currentSkill.name}</result>
64
</action>
65
<action name="delete" class="com.opensymphony.webwork.showcase.action.SkillAction" method="delete">
66
<result name="error">/empmanager/editSkill.jsp</result>
67
<result type="redirect">edit.action?skillName=$
{currentSkill.name}</result>
68
</action>
69
</package>
70
71
<package name="employee" extends="default" namespace="/employee">
72
<default-interceptor-ref name="crudStack"/>
73
74
<action name="list" class="com.opensymphony.webwork.showcase.action.EmployeeAction" method="list">
75
<result>/empmanager/listEmployees.jsp</result>
76
<interceptor-ref name="basicStack"/>
77
</action>
78
<action name="edit" class="com.opensymphony.webwork.showcase.action.EmployeeAction">
79
<result>/empmanager/editEmployee.jsp</result>
80
<interceptor-ref name="crudStack"><param name="validation.excludeMethods">execute</param></interceptor-ref>
81
</action>
82
<action name="save" class="com.opensymphony.webwork.showcase.action.EmployeeAction" method="save">
83
<result name="input">/empmanager/editEmployee.jsp</result>
84
<result type="redirect">edit.action?empId=$
{currentEmployee.empId}</result>
85
</action>
86
<action name="delete" class="com.opensymphony.webwork.showcase.action.EmployeeAction" method="delete">
87
<result name="error">/empmanager/editEmployee.jsp</result>
88
<result type="redirect">edit.action?empId=$
{currentEmployee.empId}</result>
89
</action>
90
</package>
91
92
</xwork>
二 :名称空间的配置
1 :名称空间
名称空间属性允许把action配置分成不同的名称空间,这样您可以在具有不同类和参数名称空间中使用相同的名字的action了.
这一点是和Webwork1.x不同,在Webwork1.x中所有的action名字都是全局的不能再一个应用程序中重用.2 :默认名称空间
默认名称空间用""(空字符串)表示.如果系统在指定的名称空间中没有找到某个action,就会到默认名称空间中查找.你可以在所有用"extends"扩展的名称空间外配置全局action,就像Webwork 1.x那样不指定名称空间(即作为默认名称空间).
名称空间也可以用来实现系统安全,例如action名字之前可以有个路径,这个路径就是Webwork 2.0 ServletDispatcher用的名称空间,你可以在路径上使用
J2EE声明式的安全限制,这种方式很容易的实现和维护。
3 :根名称空间
Webwork中以"/"命名的名称空间叫做根名称空间,它是请求直接来自应用程序根路径的时候的名称空间.
和其他名称空间一样,如果在根名称空间中没有所需的action别名,系统会回到默认名称空间中查找.
4 :名称空间的例子
1
<package name="default">
2
<action name="foo" class="mypackage.simpleAction>
3
<result name="success" type="dispatcher">greeting.jsp</result>
4
</action>
5
<action name="bar" class="mypackage.simpleAction">
6
<result name="success" type="dispatcher">bar1.jsp</result>
7
</action>
8
</package>
9
10
<package name="mypackage1" namespace="/">
11
<action name="moo" class="mypackage.simpleActtion">
12
<result name="success" type="dispatcher">moo.jsp</result>
13
</action>
14
</package>
15
16
<package name="mypackage2" namespace="/barspace">
17
<action name="bar" class="mypackage.simpleAction">
18
<result name="success" type="dispatcher">bar2.jsp</result>
19
</action>
20
</package> 解释 :
如果请求为/barspace/bar.action,系统首先查找'/barspace'名称空间,如果找到bar action便执行,如果没有继续到默认名称空间中查找.在这个例子中'/barspace'空间中存在bar别名,所以它会被执行,如果返回success结果,请求将指向bar2.jsp.
如果请求为/barspace/foo.action,系统会在/barspace空间中查找foo这个action,如果找不到,系统继续在默认名称空间中查找.除非指定成其他的,否则默认空间是"".在我们上面的例子中,/barspace空间中没有foo这个action,这样默认空间中的/foo.action会被找到并执行.
如果请求为/moo.action,系统会在根空间('/')中查找'moo' action别名,如果没找到再到默认空间中查找.在这个例子中,moo这个action别名存在因此会被执行.如果返回success,请求指向moo.jsp.
如果请求为'/foo.action',系统会在'/'空间中查找,找到后执行,如果没有,继续查找默认空间.在本例中,foo这个action别名不存在于'/'空间,所以系统回到默认空间中查找并执行.
注意:名称空间只有一个级别.例如如果url是'/barspace/myspace/bar.action',Webwork先试着查找'/barspace/myspace',在本例中是不存在的.接着就直接到 默认空间 中查找'bar'这个action别名.结果在默认空间中的bar会被执行.
三 . 包含的配置
为了方便的管理大型项目(非常多的action和配置),Webwork允许您在xwork.xml中包含其他的配置文件.
1
<xwork>
2
<include file="webwork-default.xml"/>
3
<include file="user.xml"/>
4
<include file="shoppingcart.xml"/>
5
<include file="product.xml"/>
6
.
7
</xwork>
被包含的文件必须是xwork.xml的格式(有doctype和其他每样东西),而且必须放在classpath下即
1
/WEB-INF/classes
2
/WEB-INF/lib下的jar文件 这里的大多内容由Matt Dowell提供<matt.dowell@notiva.com>
四 :Action的配置
1 . Action是Webwork的基础"工作单元".一个action一般就是一个请求(或点击按钮或提交表单).action元素有两部分:
1
一个友好的与URL相关名字 如 :saveForm.action
2
一个负责"处理"的类. 例子 :
1
<action name="formTest" class="com.opensymphony.webwork.example.FormAction" method="processForm">
可选属性"method"用来告诉WebWork调用action的那个方法.
1
如果method属性为空,WebWork调用默认调用*execute*()方法.
2
如果Action类中既没有execute()方法也没有在xml文件中指定其他方法,WebWork会抛出异常. 您也可以在您的表单中用"actionName!something"的方式告诉WebWork调用Action类中的"something"方法.例如"formTest!save.action"会调用FormAction类中的"save"方法.这个方法必须是public且没有参数.
1
public String save() throws Exception
{
2

3
return SUCCESS;
4
} actionName"的所有配置包括拦截器和返回类型等都会被"actionName!something"使用.
2 . Action的类属性可以像下面一样省略 (没有指出负责处理的类和方法):
1
<action name="myAction">
2
.
3
</action> 在这种情况下,会缺省使用com.opensymphony.xwork.ActionSupport 类,它有一个execute()方法,缺省返回SUCCESS.
3 . 默认Action引用
从Webwork2.2.1开始您也可以指定一个当xwork.xml中找不到指定的action时执行的默认action.这一特性主要是用来满足为创建非常简单或相似的action类或元素的需求.默认action名可以在package元素里面这样配置:
1
<package name="myPackage"
.>
2

3
4
<default-action-ref name="simpleViewResultAction">
5
6
<action name="simpleViewResultAction" class="SimpleViewResultAction">
7
<result type="velocity">$
{successUrl}</result>
8
<result name="error" type="velocity">$
{errorUrl}</result>
9
<result name="input" type="velocity">$
{inputUrl}</result>
10
</action>
11
12
13
</package> 当心 : 应该保证在每个名称空间中只有一个默认action被配置.因为如果你在同一个空间里配置了多个默认aciton,系统就不知道那个是默认的了.
注意 :
注意第一个result的属性省略了,WebWork缺省会把它当作"success". 在这种情况下,如果请求到action的映射没有在这个包里定义,它会自动转向到别名为 "simpleViewResultAction" 的action来执行.
五 :结果的配置
Result是Action返回的表示Action执行情况的字符串常量.WebWork定义了一些默认结果:
1
error
2
input
3
login
4
none
5
success. 开发者当然也可以根据应用情况自由的定义结果.结果以"名字-值"的形式影射到结果类型.
5.1 :结果类型
在Action执行完,一个结果返回后决定发生什么事的类。开发者可以自由的根据他们的应用和环境的需要创建自己的Result类型。
例如在WebWork2中,Servlet和Velocity结果类型已经被创建用来显示web应用程序的画面。注意: 所有的webwork内建的Result类型都实现了
com.opensymphony.xwork.Result接口. 这个接口是所有action执行结果的通用接口,不管这个结果是用来 :
1
显示一个网页
2
产生一个email
3
发送一个JMS消息,等. Result类型配置中定义了一些类,把它们映射为action配置中可以引用的名字. 也就是为这些类创建便于记忆的键-值对.
webwork-default.xml 节选 :
1

2
<result-types>
3
<result-type name="dispatcher" class="com.opensymphony.webwork.dispatcher.ServletDispatcherResult" default="true"/>
4
<result-type name="redirect" class="com.opensymphony.webwork.dispatcher.ServletRedirectResult"/>
5
<result-type name="velocity" class="com.opensymphony.webwork.dispatcher.VelocityResult"/>
6
<result-type name="chain" class="com.opensymphony.xwork.ActionChainResult"/>
7
<result-type name="xslt" class="com.opensymphony.webwork.views.xslt.XSLTResult"/>
8
<result-type name="jasper" class="com.opensymphony.webwork.views.jasperreports.JasperReportsResult"/>
9
<result-type name="freemarker" class="com.opensymphony.webwork.views.freemarker.FreemarkerResult"/>
10
<result-type name="httpheader" class="com.opensymphony.webwork.dispatcher.HttpHeaderResult"/>
11
<result-type name="stream" class="com.opensymphony.webwork.dispatcher.StreamResult"/>
12
<result-type name="plaintext" class="com.opensymphony.webwork.dispatcher.PlainTextResult" />
13
</result-types>
14

xwork.xml 节选 :
1
<include file="webwork-default.xml"/>
2
3
<package name="myPackage" extends="default">
4
<action name="bar" class="myPackage.barAction">
5
<!-- default result type is "dispatcher" -->
6
<!-- default result name is "success" -->
7
<result>foo.jsp</result>
8
<result name="error">error.jsp</result>
9
</result>
10
</action>
11
</package>
Webwork提供了一些com.opensymphony.xwork.Result接口的实现来使你的action可以容易的用户交互.这些Result类型包括:
1
Chain Result - 用于 Action Chaining
2
Dispatcher Result - 用于 JSP 整合
3
FreeMarker Result - 用于 FreeMarker 整合
4
HttpHeader Result - 用于控制特殊的HTTP行为
5
JasperReports Result - 用于 JasperReports 整合
6
Redirect Result - 用于直接跳转到例外的URL
7
Redirect Action Result - 用于直接跳转到另外的action
8
Stream Result - 用于向浏览器返回一个InputStream (一般用于文件下载)
9
Velocity Result - 用于 Velocity 整合
10
XSL Result - 用于 XML/XSLT 整合
11
PlainText Result - 用于显示某个页面的原始的文本 (例如 jsp, html 等) Result定义在xwork xml配置文件(xwork.xml)中的action标签里。如果location参数是result标签的唯一的参数,你可以这样简化:
1
<action name="bar" class="myPackage.barAction">
2
<result name="success" type="dispatcher">
3
<param name="location">foo.jsp</param>
4
</result>
5
</action> 或者
1
<action name="bar" class="myPackage.barAction">
2
<result name="success" type="dispatcher">foo.jsp</result>
3
</action>
如果你继承了webwork-default.xml, 那么默认的返回类型是"dispatcher". 同样,如果你没有指定result的名字,默认将是"success". 就是说你可以如下简化:
1
<action name="bar" class="myPackage.barAction">
2
<result>foo.jsp</result>
3
</action>
注意 : Parse属性允许的location参数作为表达式.例如你可以这样用:
1
<result name="success" type="redirect">/displayCart.action?userId=$
{userId}</result> 注意 : 你也可以指定全局Result以便在多个action中使用. 当要为很多不同的action添加相同的结果是这样会节省时间.
5.2 :全局结果
WebWork允许您为所有Action配置定义一些默认的result映射,它会自动的被这个包中所有的Action以及所有扩展包继承,换句话说 :
如果您在多个Action中使用相同的result映射,您可以把它配置成全局的Result.例子 :
1
<package name="default">
2
.
3
<global-results>
4
<result name="login" type="dispatcher">
5
<param name="location">login.jsp</param>
6
</result>
7
</global-results>
8
<action name="foo" class="mypackage.fooAction">
9
<result name="success" type="dispatcher">bar.jsp</result>
10
</action>
11
<action name="submitForm" class="mypackage.submitFormAction">
12
<result name="success" type="dispatcher">submitSuccess.jsp</result>
13
</action>
14

15
</package> 这样配置也可以 :
1
<package name="default">
2
.
3
<action name="foo" class="mypackage.fooAction">
4
<result name="success" type="dispatcher">bar.jsp</result>
5
<result name="login" type="dispatcher">login.jsp</result>
6
</action>
7
<action name="submitForm" class="mypackage.submitFormAction">
8
<result name="success" type="dispatcher">submitSuccess.jsp</result>
9
<result name="login" type="dispatcher">login.jsp</result>
10
</action>
11

12
</package>
5.3 默认结果
在WebWork中您可以为您的Action定义默认的结果类型.这样当使用默认结果类型时就不用指定了.如果一个包扩展另一个包,且您没有为子包指定新的默认结果类型,那么当子包的result标签中没有指定结果类型时就会使用父包中的默认类型.
<!-- parts of xwork.xml -->
1
.
2
3
<result-types>
4
<result-type name="dispatcher" class="com.opensymphony.webwork.dispatcher.ServletDispatcherResult" default="true"/>
5
<result-type name="redirect" class="com.opensymphony.webwork.dispatcher.ServletRedirectResult"/>
6
<result-type name="velocity" class="com.opensymphony.webwork.dispatcher.VelocityResult"/>
7
</result-types>
8
9
.
10
11
<action name="bar" class="myPackage.barAction">
12
13
<!-- this result uses dispatcher, so you can omit the type="dispatcher" if you want -->
14
<result name="success">foo.jsp</result>
15
16
<!-- this result uses velocity result, so the type needs to be specified -->
17
<result name="error" type="velocity">error.vm</result>
18
19
</action>
20
21
.
六 . 拦截器的配置
拦截器允许您定义一些能在一个action执行的前后执行的代码.它是做web应用程序时很有用的工具.最常见的拦截器实现可以是:
1:安全检查(确保访问者是登陆用户)
2:跟踪日志(记录每个action)
3:效率瓶颈检查(记录每个action开始和结束的时间以检查程序中的瓶颈) 您也可以把拦截器连在一起组成 拦截器栈.如果您想在action执行前同时做登陆检查,安全检查和记录日志,可以定义一个拦截器的包.
拦截器必须事先定义(命名)好,然后可以连在一起组成一个栈.
1
<interceptors>
2
<interceptor name="security" class="com.mycompany.security.SecurityInterceptor"/>
3
<interceptor-stack name="defaultComponentStack">
4
<interceptor-ref name="component"/>
5
<interceptor-ref name="defaultStack"/>
6
</interceptor-stack>
7
</interceptors> 在action中这样使用.
1
<action name="VelocityCounter" class="com.opensymphony.webwork.example.counter.SimpleCounter">
2
<result name="success">
</result>
3
<interceptor-ref name="defaultComponentStack"/>
4
</action>
注意:引用名既可以是拦截器名也可以是栈名
拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了一种可以提取action中可重用的部分的方式.
拦截器必须是无状态的。
拦截器可以选择短路一个action调用,然后返回一个结果码,如 :
com.opensymphony.xwork.Action#SUCCESS)也可以选择在ActionInvocation#invoke()之前或者之后做一些处理。
拦截器以key-value对的方式定义在xwork配置文件中.下面是定义在webwork-default.xml的拦截器.如果您继承webwork-default包,您就可以使用下面的拦截器.否则您就必须在自己的包中的<interceptors>标签中定义name-class对.

抽象的拦截器可以通过指定included/excluded方法列表来实现可选择性
1
excludeMethods - 被排除的方法
2
includeMethods - 被包含的方法 注意: 如果一个方法的名字同时出现在includeMethods和excludeMethods里,它会被当作包含的方法。也就是,includeMethods优先于excludeMethods.
扩展了这一能力的拦截器有:
1
TokenInterceptor
2
TokenSessionStoreInterceptor
3
DefaultWorkflowInterceptor
4
ValidationInterceptor
拦截器的参数可以通过如下方式被覆盖
方法1: (整个默认栈都被复制,然后根据需要改变参数)
1
<action name="myAction" class="myActionClass">
2
<interceptor-ref name="exception"/>
3
<interceptor-ref name="alias"/>
4
<interceptor-ref name="params"/>
5
<interceptor-ref name="servlet-config"/>
6
<interceptor-ref name="prepare"/>
7
<interceptor-ref name="i18n"/>
8
<interceptor-ref name="chain"/>
9
<interceptor-ref name="model-driven"/>
10
<interceptor-ref name="fileUpload"/>
11
<interceptor-ref name="static-params"/>
12
<interceptor-ref name="params"/>
13
<interceptor-ref name="conversionError"/>
14
<interceptor-ref name="validation">
15
<param name="excludeMethods">myValidationExcudeMethod</param>
16
</interceptor-ref>
17
<interceptor-ref name="workflow">
18
<param name="excludeMethods">myWorkflowExcludeMethod</param>
19
</interceptor-ref>
20
</action> 方法2: (引用了已经存在的拦截器栈,覆盖其中的部分拦截器)
1
<action name="myAction" class="myActionClass">
2
<interceptor-ref name="defaultStack">
3
<param name="validator.excludeMethods">myValidationExcludeMethod</param>
4
<param name="workflow.excludeMethods">myWorkflowExcludeMethod</param>
5
</interceptor-ref>
6
</action> 在第二个方法中,我们引用了已经存在的拦截器栈。在这个例子中这个栈是default-stack,然后覆盖了validator和workflow拦截器的excludeMethods参数。注意在这个标签的name属性中有一个点(.),点之前的单词表示要被覆盖参数的拦截器名,点之后的表示参数。形式如下:
<拦截器名>.<参数名>
也要注意到,在这个例子中如果name属性用来表示一个拦截器栈,就像指向一个拦截器本身,那只能用上面描述的第一种方法.
拦截器提供了极好的方式去包装 前/后 处理.这种概念减少了代码重复(就像AOP).
1
<interceptor-stack name="xaStack">
2
<interceptor-ref name="thisWillRunFirstInterceptor"/>
3
<interceptor-ref name="thisWillRunNextInterceptor"/>
4
<interceptor-ref name="followedByThisInterceptor"/>
5
<interceptor-ref name="thisWillRunLastInterceptor"/>
6
</interceptor-stack>
注意一些拦截器会打乱stack/chain/flow...所以顺序非常重要.
实现了
com.opensymphony.xwork.interceptor.PreResultListener的拦截器在Action之后Result之前执行.
http://wiki.javascud.org/display/ww2cndoc/Interceptors
七 . 表现层
WebWork支持的表现层技术
1
JSP
2
Velocity
3
Freemaker
4
Xslt
5
Groovy等 .这个例子中我们使用JSP文件.WebWork提供了一套标签库(taglibs).你可以在JSP文件中把这些标签作为组件使用.这里是form.jsp页的一部分.
1
<%@ taglib prefix="ww" uri="webwork" %>
2
<html>
3
<head><title>Webwork Form Example</title></head>
4
<body>
5
<ww:form name="myForm" action="'formTest'" namespace="/" method="POST">
6
<table>
7
<ww:textfield label="First Name" name="'formBean.firstName'" value="formBean.firstName"/>
8
<ww:textfield label="Last Name" name="'formBean.lastName'" value="formBean.lastName"/>
9
<ww:submit value="Save Form"/>
10
</table>
11
</ww:form>
12
</body>
(译者注:上面这段代码中的语法使用的是老的标签语法,如果使用alt语法则略有不同)
处理流程如下:
- WebWork会对以 .action 结尾的URI进行处理(定义在 web.xml 文件中)(译者注:URI的模式是可以替换的)
- WebWork查找名为 formTest 的action,调用定义在其上的拦截器.
- WebWork翻译 formTest 然后决定调用定义在xwork.xml文件中的 com.opensymphony.webwork.example.FormAction 类中的 processForm 方法.
- 这个方法执行成功后返回 SUCCESS 作为结果
- WebWork按照xwork.xml中的定义把 SUCCESS 转义为 formSuccess.jsp 然后定位到这个页面.