[1]
完整的
action
<action path="/aFullAction"
type="somePackage.someActionClass">
name="someForm"
input="someJSP.jsp"
<forward name="successful" path="someJSP.jsp"/>
<forward name="failed" path="someOtherJSP.jsp"/>
</action>
type="somePackage.someActionClass">
name="someForm"
input="someJSP.jsp"
<forward name="successful" path="someJSP.jsp"/>
<forward name="failed" path="someOtherJSP.jsp"/>
</action>
首先,
Struts
的
ActionServlet
接收到一个请求,然后根据
struts-config.xml
的配置定位到相应的
mapping
(映射);接下来如果
form
的范围是
request
或者在定义的范围中找不到这个
form
,创建一个新的
form
实例;取得
form
实例以后,调用其
reset ()
方法,然后将表单中的参数放入
form
,如果
validate
属性不为
false
,调用
validate()
方法;如果
validate()
返回非空的
ActionErrors
,将会被转到
input
属性指定的
URI
,如果返回空的
ActionErrors
,那么执行
Action
的
execute()
方法,根据返回的
ActionForward
确定目标
URI
。
这样做的效果是:
execute()
仅当
validate()
成功以后才执行;
input
属性指定的是一个
URI
。
[2] 仅有 Form 的 action
<action path="/aFormOnlyAction"
type="org.apache.struts.actions.ForwardAction"
name="someForm"
input="someJSP.jsp"
parameter="someOtherJSP.jsp"
/>
type="org.apache.struts.actions.ForwardAction"
name="someForm"
input="someJSP.jsp"
parameter="someOtherJSP.jsp"
/>
首先,
Struts
会在定义的
scope
搜寻
someForm
,如果找到则重用,如果找不到则新建一个实例;取得
form
实例以后,调用其
reset()
方法,然后将表单中的参数放入
form
,如果
validate
属性不为
false
,调用
validate()
方法;如果
validate()
返回非空的
ActionErrors
,将会被转到
input
属性指定的
URI
,如果返回空的
ActionErrors
,那么转到
parameter
属性指定的目标
URI
。
这样做的效果是:没有
action
类可以存放我们的业务逻辑,所以所有需要写入的逻辑都只能写到
form
的
reset()
或者
validate()
方法中。
validate()
的作用是验证和访问业务层。因为这里的
action
映射不包括
forward
(也没有意义),所以不能重定向,只能用默认的那个
forward
。这种仅有
form
的
action
可以用来处理数据获取并
forward
到另一个
JSP
来显示。
[3] 仅有 Action 的 action
<action path="/anActionOnlyAction"
type="somePackage.someActionClass">
input="someJSP.jsp"
<forward name="successful" path="someJSP.jsp"/>
<forward name="failed" path="someOtherJSP.jsp"/>
</action>
type="somePackage.someActionClass">
input="someJSP.jsp"
<forward name="successful" path="someJSP.jsp"/>
<forward name="failed" path="someOtherJSP.jsp"/>
</action>
首先,
ActionServlet
接收到请求后,取得
action
类实例,调用
execute()
方法;然后根据返回的
ActionForward
在配置中找
forward
,
forward
到指定的
URI
或
action
。
这样做的效果是:没有
form
实例被传入
execute()
方法,于是
execute()
必须自己从请求中获取参数。
Action
可以被
forward
或者重定向。这种
action
不能处理通过
HTML FORM
提交的请求,只能处理链接式的请求。
[4] 仅有 JSP 的 action
<action path="/aJSPOnlyAction"
type="org.apache.struts.actions.ForwardAction"
parameter="someOtherJSP.jsp"
/>
type="org.apache.struts.actions.ForwardAction"
parameter="someOtherJSP.jsp"
/>
首先,
ActionServlet
接到请求后调用
ForwardAction
的
execute()
方法,
execute()
根据配置的
parameter
属性值来
forward
到那个
URI
。
这样做的效果是:没有任何
form
被实例化,比较现实的情形可能是
form
在
request
更高级别的范围中定义;或者这个
action
被用作在应用程序编译好后充当系统参数,只需要更改这个配置文件而不需要重新编译系统。
[5] 两个 action 对应一个 form
<action path="/anAction"
type="somePackage.someActionClass">
name="someForm"
input="someJSP.jsp"
<forward name="successful" path="/anotherAction.do"/>
</action>
<action path="/anotherAction"
type="somePackage.someOtherActionClass">
name="someForm"
input="someOtherJSP.jsp"
<forward name="successful" path="someResultJSP.jsp"/>
</action>
type="somePackage.someActionClass">
name="someForm"
input="someJSP.jsp"
<forward name="successful" path="/anotherAction.do"/>
</action>
<action path="/anotherAction"
type="somePackage.someOtherActionClass">
name="someForm"
input="someOtherJSP.jsp"
<forward name="successful" path="someResultJSP.jsp"/>
</action>
就每个单独的
action
来讲,处理上并没有和完整的
action
有什么实质的区别。这个组合模式可以被用来传递命令对象(
form
)。需要注意的是在后一个
action
中同样会调用
form
的
reset()
和
validate()
方法,因此我们必须确保
form
中的信息不被重写。
处理的方式大致分为两种:
a)
在
request
中放入一个指示器表明前一个
action
有意向后一个
action
传递
form
,从而在后一个
action
可以保留那个
form
中的值,这一方式只能在使用
forward
时使用。
b)
当使用
redirect
而不是
forward
时,可以把指示器放在
session
或更高的级别,在命令链的最后一环将这个指示器清除。
[6] 两个 action 对应两个 form
<action path="/anAction"
type="somePackage.someActionClass">
name="someForm"
input="someJSP.jsp"
<forward name="successful" path="/anotherAction.do" redirect="true"/>
</action>
<action path="/anotherAction"
type="somePackage.someOtherActionClass">"
name="someOtherForm"
input="someOtherJSP.jsp"
<forward name="successful" path="someResultJSP.jsp"/>
</action>
type="somePackage.someActionClass">
name="someForm"
input="someJSP.jsp"
<forward name="successful" path="/anotherAction.do" redirect="true"/>
</action>
<action path="/anotherAction"
type="somePackage.someOtherActionClass">"
name="someOtherForm"
input="someOtherJSP.jsp"
<forward name="successful" path="someResultJSP.jsp"/>
</action>
这个组合方式跟前一种在流程上没有太大区别,只是我们现在对于两个
action
分别提供了
form
,于是代码看上去更加清晰。于是我们可以分别处理
WEB
应用程序的输入和输出。值得注意的是,后一个
action
同样会尝试往
form
中写入那些参数,不过我们可以这样处理:
a)
在后一个
form
中使用另一套属性名;
b)
只提供
getter
而不提供
setter
。
大致的处理是这样:
前一个 action 接收输入、验证、然后将数据写入业务层或持久层,重定向到后一个 action ,后一个 action 手动的从业务层 / 持久层取出数据,写入 form (通过其他方式),交给前台 JSP 显示。
前一个 action 接收输入、验证、然后将数据写入业务层或持久层,重定向到后一个 action ,后一个 action 手动的从业务层 / 持久层取出数据,写入 form (通过其他方式),交给前台 JSP 显示。
这样做的好处是不必保留输入
form
中的值,因此可以使用
redirect
而不是
forward
。这样就降低了两个
action
之间的耦合度,同时也避免了不必要的重复提交。