strus2中获取表单数据有两种方式属性驱动和模型驱动,属性驱动即使用Action的属性元素封装请求参数,而模型驱动是使用javaBean来封装来回请求参数。
【struts2中模型驱动的使用方法】
一个Action要想成为模型驱动的话,就必须实现ModelDriven接口,请看下面一个例子:
上面的代码,首先BaseAction实现了ModelDriven接口,在BaseAction生命了实例变量model,然后再BaseAction的子类中就可以使用model来进行参数的传递。
UserAction的部分代码:
【struts2中模型驱动原理】
要说驱动模型实现,首先先介绍以下ModelDrivenInterceptor,该拦截器处于defaultStack第九的位置。ModelDrivenInterceptor拦截器主要做的事就是调用Action的getModel()方法然后把返回的model压入值栈。下面是该拦截器intercept方法源码:
@Override
public String intercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();//获取当前正在执行的Action
//如果Action实现了ModelDriven接口
if (action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven) action;
ValueStack stack = invocation.getStack();
Object model = modelDriven.getModel();//通过getModel方法获取model
if (model != null) {//如果model不为null则把model压入值栈
stack.push(model);
}
if (refreshModelBeforeResult) {//在执行Result之前是否要更新model对象,默认为false
invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
}
}
return invocation.invoke();//调用下一个拦截器
}
此方法就是就是把getModel方法返回的结果压入值栈而已,我们一般实现这个接口是利用压入值栈的model对象接收从页面提交过来的数据,因为Action也是在值栈中,而struts2在赋值参数的时候是在值栈从栈顶往栈底寻找有相应setter方法的对象,而这时model压入了值栈,它是处于栈顶的,所以从页面提交过来的参数也就被model对象接收了。
下面是struts2请求执行流程图:
对于属性驱动,我们需要在Action中定义与表单元素对应的所有的属性,因而在Action中会出现很多的getter和setter方法,使得Action代码量增加了很多,而且不利于封装和继承,模型驱动使得Action更加简洁,可以使Action更加专注于是控制业务逻辑。