阅读源码可以得知若 Action 实现了 Preparable 接口, 则 Struts 将尝试执行 prepare[ActionMethodName] 方法, 若 prepare[ActionMethodName] 不存在, 则将尝试执行 prepareDo[ActionMethodName] 方法.若都不存在, 就都不执行
若 PrepareInterceptor 的 alwaysInvokePrepare 属性为 false, 则 Struts2 将不会调用实现了 Preparable 接口的 Action 的 prepare() 方法,即 prepare() 可以不去实现而为每一个 Action 方法准备一个 prepareXxx 或 prepareDoXxx 方法,然后将 alwaysInvokePrepare 属性设为 false,那么每次执行就不会触发 prepare 方法
若实现了此接口,那么每个 prepareXxx 方法就会为对应的 Xxx 方法准备一个 Model,利用 getModel() 方法将其置于栈顶,而不需要 empId 去判断,影响程序效率。说白了就是 prepareXxx 方法是为 getModel 方法准备返回对象的
最终代码(EmployeeCurd.java)
public class EmployeeCurd implements RequestAware, ModelDriven<Employoee>, Preparable { private Dao dao = new Dao(); private Map<String, Object> requestMap; private Employoee employoee; private Integer empId; public Integer getEmpId() { return empId; } public void setEmpId(Integer empId) { this.empId = empId; } public String delete() { dao.deleteEmp(String.valueOf(empId)); return "delete"; } /* * 更新和添加一样,需要准备一个新的 employee 对象 * */ public String update() { dao.updateEmp(employoee); return "update"; } /* * 准备一个新的 Employee 对象 * */ public void prepareUpdate() { employoee = new Employoee(); } /* * * 添加到栈顶,使用 ModelDriven 拦截器和 paramsPrepareParmas 拦截器栈之后我们利用 ModelDriven 拦截器将 employee 对象添加到 * 栈顶,不需要为 Action 类创建对应的属性,利用 ModelDriven 将对应的对象添加到栈顶之后执行 params 拦截器时便将请求参数和栈顶 * 对象对应的属性赋值,使用了 prepare 拦截器之后我们在执行 ModelDriven 拦截器之前利用 prepare 拦截器准备好 model 不需要在 * ModelDriven 拦截器中创建对应的对象 * */ public String add() { dao.addEmp(employoee); return "add"; } /* * 利用 ModelDriven 和 prepare 拦截器将对应的 model 添加到栈顶之后并利用 params 拦截器为其赋值,填充栈顶对象,执行完所有的 * 拦截器之后执行 add() 方法,此时的 employee 对象便为已经填充的对象 * */ public void prepareAdd() { employoee = new Employoee(); } /* * 将已有的数据显示的时候不需要准备 model,所以不需要准备 prepareXxx 方法 * */ public String show() { List<Employoee> employees = dao.getEmployee(); requestMap.put("empList", employees); return "show"; } public String edit() { return "edit"; } /* * 对现有的内容做出修改的时候需要进行回显,所以需要使用 prepare 拦截器为 ModelDriven 拦截器准备 model,这样的话便可 * 利用现有的对象实现回显(回显就是利用与栈顶对象匹配的元素去回显) * */ public void prepareEdit() { employoee = dao.getEmployee(String.valueOf(empId)); } @Override public void setRequest(Map<String, Object> map) { this.requestMap = map; } /* * 实现 ModelDriven 拦截器,getModel 方法将把返回对象置于栈顶 * */ @Override public Employoee getModel() { return employoee; } /* * 若不设置 PrepareInterceptor 拦截器的 alwaysInvokePrepare 属性为 false,那么每次调用 action 方法都会执行 prepare 方法 * 若设置其为 false,那么每次调用 Action 方法的时候就不会去调用 prepare 方法 * 我们可以为某些 Action 方法实现 prepareXxx 方法,其为私有定制的方法等同于 prepare 方法,其功能和 prepare 方法等效,都是 * 为 modelDriven 拦截器准备 model,然后利用 modelDriven 将 model 放置在栈顶,这样的话 getModel 和 prepare 方法就不需要 * 去判断是新建对象还是从现有的中获取。 * 在 ModelDriven 拦截器之前执行 params 拦截器时是为栈顶对象 Action 类对应的属性赋值,该例中 Action 类的属性只有 empId * */ @Override public void prepare() throws Exception { System.out.println("prepare"); } }此时的 Action 类的 action 方法就非常的简洁,不会在有其他的冗余问题。