在struts2中,其拦截器为框架精华部分,而二次参数拦截器paramsPrepareParamsStack 对于解决数据回显,对象修改属性丢失的问题有着很良好的处理机制。
在 struts-default.xml 中的默认拦截器配置中有以下部分(可自行查找源码,通常为:struts-2.5.2srccoresrcmain esources):
1 <interceptor-stack name="paramsPrepareParamsStack"> 2 <interceptor-ref name="exception"/> 3 <interceptor-ref name="alias"/> 4 <interceptor-ref name="i18n"/> 5 <interceptor-ref name="checkbox"/> 6 <interceptor-ref name="datetime"/> 7 <interceptor-ref name="multiselect"/> 8 <interceptor-ref name="params"/> <!-- 把jsp里提交的参数封装action里面对象--- (1) --> 9 <interceptor-ref name="servletConfig"/> 10 <interceptor-ref name="prepare"/> <!-- 前置方法---------------------------- (2) --> 11 <interceptor-ref name="chain"/> 12 <interceptor-ref name="modelDriven"/> <!-- 把非空的model放置栈顶---------------- (3) --> 13 <interceptor-ref name="fileUpload"/> 14 <interceptor-ref name="staticParams"/> 15 <interceptor-ref name="actionMappingParams"/> 16 <interceptor-ref name="params"/> <!-- 把jsp提交参数封装action里面对象------- (4) --> 17 <interceptor-ref name="conversionError"/> <!-- 转换异常 --> 18 <interceptor-ref name="validation"> <!-- 验证异常 --> 19 <param name="excludeMethods">input,back,cancel,browse</param> 20 </interceptor-ref> 21 <interceptor-ref name="workflow"> <!-- 处理上面2个异常 --> 22 <param name="excludeMethods">input,back,cancel,browse</param> <!-- 排除不需要的 --> 23 </interceptor-ref> 24 </interceptor-stack>
(1)、关于 <interceptor-ref name="params"/>
把页面提交的参数封装到Action中的对象里面,只有在Action中声明的属性才能接受和封装,即只接受给定的属性,(多个参数时过滤后也只封装与给定条件吻合的)
同时Action必须提供get,set方法.
1 //例: 2 private Long id; 3 public Long getId() { 4 return id; 5 } 6 public void setId(Long id) { 7 this.id = id; 8 }
进入此Action中,栈顶元素为:EmployeeAction
(默认情况下访问那个action,那个action就在栈顶)
(2)、<interceptor-ref name="prepare"/>
EmlpoyeeAction.java
1 /** 2 * 使用action中配置的拦截器相应函数 3 * 自动在input方法之前自动执行 4 * 完成参数回显 5 */ 6 public void prepareInput() throws Exception { 7 if (id != null) { 8 employee = employeeService.get(id); // 回显 9 } 10 } 11 12 // 自动在save方法之前自动执行 13 // 解决参数丢失的问题 14 public void prepareSave() throws Exception { 15 if (id != null) { 16 employee = employeeService.get(id); // 保证属性不丢失关键代码 17 } else { 18 employee = new Employee(); 19 } 20 } 21 22 23 // 最后执行public void prepare()方法 24 // 自动在所有strtus方法之前自动执行:拦截器的顺序问题 25 @Override 26 public void prepare() throws Exception { 27 //相关功能,或者留空 28 }
(3)、<interceptor-ref name="modelDriven"/> 驱动模型后,伴随压栈操作
EmployeeAction.java
1 @Override 2 public Employee getModel() { 3 return employee; //这里返回preoare经过验证拿到的对象 4 }
进入此Action中,栈顶元素为:Employee
(因为在经过二次参数拦截器的时候,里面无论是从数据库拿还是new一个对象,此时都有一个相对于之前内容不相同的同一类对象,所以,会执行压栈操作,将拿到的对象放在栈顶)
重点:
<interceptor-ref name="params"/>--------------------------------------------------------------------------------(4)
装的对象(1),和经过之前prepareXxx()方法获取到的对象(2),
即此时栈顶的对象(2)进行属性的对比,如果1中的属性缺失,会将缺失属性补足,然后进行后续操作.
最后:
执行Action中页面调用的方法,返回结果视图,进行页面跳转.
另外,配置玩二次参数拦截器之后,再检查一遍struts.xml配置文件中的内容