刘文涛

Pattern,UML,Struts2,Hibernate3,Spring2,Oracle,mysql,weblogic,tomcat,compass,lucene,nutch,sitemesh,freemarker,div,css,ExtJs,Flex,seo

   :: 首页 ::  ::  ::  :: 管理 ::
组成Action配置的各个元素,例如 :

1actions
2interceptors
3results
4package

一 :包的配置

Packages是把

1Actions
2Results
3Result Types
4Interceptors
5Stacks

分组成逻辑单元的一种方式,以分享一些共同设置.

包跟对象一样可以扩展,也可以被""包覆盖部分属性.




1 : "extends"属性使一个package可以继承一个或多个前面package中的 :

1拦截器
2拦截器栈
3action等配置

注意,配置文件是被至上而下处理的,所以"被继承"的包必需定义在"继承"包的上面.

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且没有参数.

1public 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定义了一些默认结果:

1error
2input
3login
4none
5success.

开发者当然也可以根据应用情况自由的定义结果.结果以"名字-值"的形式影射到结果类型.

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类型包括:

 1Chain Result - 用于 Action Chaining 
 2Dispatcher Result - 用于 JSP 整合 
 3FreeMarker Result - 用于 FreeMarker 整合 
 4HttpHeader Result - 用于控制特殊的HTTP行为 
 5JasperReports Result - 用于 JasperReports 整合 
 6Redirect Result - 用于直接跳转到例外的URL 
 7Redirect Action Result - 用于直接跳转到另外的action 
 8Stream Result - 用于向浏览器返回一个InputStream (一般用于文件下载) 
 9Velocity Result - 用于 Velocity 整合 
10XSL Result - 用于 XML/XSLT 整合 
11PlainText 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方法列表来实现可选择性

1excludeMethods - 被排除的方法 
2includeMethods - 被包含的方法 

注意: 如果一个方法的名字同时出现在includeMethods和excludeMethods里,它会被当作包含的方法。也就是,includeMethods优先于excludeMethods.

扩展了这一能力的拦截器有:

1TokenInterceptor 
2TokenSessionStoreInterceptor 
3DefaultWorkflowInterceptor 
4ValidationInterceptor 


拦截器的参数可以通过如下方式被覆盖

方法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支持的表现层技术

1JSP
2Velocity
3Freemaker
4Xslt
5Groovy等

.这个例子中我们使用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语法则略有不同)

处理流程如下:

  1. WebWork会对以 .action 结尾的URI进行处理(定义在 web.xml 文件中)(译者注:URI的模式是可以替换的)
  2. WebWork查找名为 formTest 的action,调用定义在其上的拦截器.
  3. WebWork翻译 formTest 然后决定调用定义在xwork.xml文件中的 com.opensymphony.webwork.example.FormAction 类中的 processForm 方法.
  4. 这个方法执行成功后返回 SUCCESS 作为结果
  5. WebWork按照xwork.xml中的定义把 SUCCESS 转义为 formSuccess.jsp 然后定位到这个页面.
posted on 2006-08-25 09:49 刘文涛 阅读(420) 评论(0)  编辑  收藏