Struts2的运行流程
1、ActionProxy是Action的一个代理类,也就是说Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方法,而该方法又调用了ActionInvocation.invoke()方法,上图中的StrutsActionProxy类实现类ActionProxy代理类。
Params拦截器
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">^action:.*,^method:.*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
<interceptor-ref name="deprecation"/>
</interceptor-stack>
Params拦截器是struts2默认的拦截器之一,其作用如下:
Parameters
拦截器将把表单字段映射到
ValueStack
栈的栈顶对象的各个属性中
.
如果某个字段在模型里没有匹配的属性
,
Param
拦截器将尝试
ValueStack
栈中的下一个对象
ModelDriven拦截器
ModelDrivenInterceptor 的interceptor() 方法:
public String intercept(ActionInvocation invocation)
throws Exception
{
//获取action对象
Object action = invocation.getAction();
//检查是否实现了ModelDriven接口
if ((action instanceof ModelDriven)) {
ModelDriven modelDriven = (ModelDriven)action;
//取值栈
ValueStack stack = invocation.getStack();
//获取Action中的成员变量对象
Object model = modelDriven.getModel();
if (model != null) {
//压入值栈栈顶
stack.push(model);
}
if (refreshModelBeforeResult) {
invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
}
}
//执行下一个拦截器操作
return invocation.invoke();
}
1、在使用
Struts
作为前端的企业级应用程序时
把
Action
和
Model
清晰
地隔离开是有必要的
:
有些
Action
类
不代表
任何
Model
对象
,
它们的功能仅限于
提供视图
服务
2、当 用户触发 add 请求时 , ModelDriven 拦截器将 调用 EmployeeAction 对象的 getModel () 方法 , 并把返回的模型 (Employee 实例 ) 压入到 ValueStack 栈 .
2、当 用户触发 add 请求时 , ModelDriven 拦截器将 调用 EmployeeAction 对象的 getModel () 方法 , 并把返回的模型 (Employee 实例 ) 压入到 ValueStack 栈 .
3、接下来
Parameters
拦截器将把表单字段映射到
ValueStack
栈的栈顶对象的各个属性中
.
因为此时
ValueStack
栈的栈顶元素是刚被压入的模型
(Employee)
对象
,
所以该模型将被填充
.
如果某个字段在模型里没有匹配的属性
,
Param
拦截器将尝试
ValueStack
栈中的下一个
对象
总结:通过上述的2个拦截器,可以看出为什么Action实现ModelDriven接口之后,在Action中可以直接使用成员对象变量来接受前台提交来的属性值。
总结:通过上述的2个拦截器,可以看出为什么Action实现ModelDriven接口之后,在Action中可以直接使用成员对象变量来接受前台提交来的属性值。
Prepare拦截器
1、S
truts 2.0
中的
modelDriven
拦截器负责把
Action
类以外的一个对象压入到值栈栈顶
2、
而
prepare
拦截器负责准备为
getModel
()
方法准备
model
PrepareInterceptor拦截器用法
1、
若
Action
实现
Preparable
接口,则
Action
方法需实现
prepare()
方法
2、PrepareInterceptor 拦截器将调用 prepare() 方法, prepareActionMethodName () 方法【比如 prepareSave()------action中有一个方法名为save】 或 prepareDoActionMethodName () 方法 ]
2、PrepareInterceptor 拦截器将调用 prepare() 方法, prepareActionMethodName () 方法【比如 prepareSave()------action中有一个方法名为save】 或 prepareDoActionMethodName () 方法 ]
3、
PrepareInterceptor
拦截器根据
firstCallPrepareDo
属性决定获取
prepareActionMethodName
、
prepareDoActionMethodName
的顺序。默认情况下先获取
prepareActionMethodName
(),
如果没有该方法,就寻找
prepare
Do
ActionMethodName
()
。如果找到对应的方法就调用该方法
4、
PrepareInterceptor
拦截器会根据
alwaysInvokePrepare
属性决定是否执行
prepare()
方法
paramsPrepareParamsStack拦截器栈
1、paramsPrepareParamsStack
从字面上理解来说, 这个
stack
的拦截器调用的顺序为:首先
params
,
然后
prepare,
接下来
modelDriven
,
最后再
params
2、Struts 2.0
的设计上要求
modelDriven
在
params
之前调用,而业务中
prepare
要负责准备
model,
准备
model
又需要参数,这就需要在
prepare
之前运行
params
拦截器设置相关参数,这个也就是创建
paramsPrepareParamsStack
的原因。
3、
流程如下:
– 1. params 拦截器首先给 action 中的相关参数赋值,如 id– 2.prepare 拦截器执行 prepare 方法, prepare 方法中会根据参数,如 id, 去调用业务逻辑,设置 model 对象– 3. modelDriven 拦截器将 model 对象压入 value stack, 这里的 model 对象就是在 prepare 中创建的– 4. params 拦截器再将参数赋值给 model 对象– 5. action 的业务逻辑执行
<interceptor-stack name="paramsPrepareParamsStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="params">
<param name="excludeParams">^action:.*,^method:.*</param>
</interceptor-ref>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">^action:.*,^method:.*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>