User model = new User(); --- ModelDriver<User>
如果在action中实现了ModelDriver同时还在method中给model赋值了,这个时候要注意,在执行action之前model已经被压入栈顶,及时你在method中重新赋值也不会有任何影响。
栈顶指向的是实例化action时候的model,即new User(),但是在执行action指定方法时候,model = 新对象引用。现在栈顶指向的是旧的user对象,而model变量指向新user对象。
1.可以直接把栈顶元素删除然后将user压入栈顶
2.可以使用BeanUtils给model赋值,这样就能改变对象的属性
3.可以实现Preparable接口,将需要执行方法前缀指定为下面两者之一
private final static String PREPARE_PREFIX = "prepare";
private final static String ALT_PREPARE_PREFIX = "prepareDo";
但是要注意,因为PreparableInterceptor在默认栈中是比ParametersInterceptor更早执行的,所以要注意这点,也可以使用paramsPrepareParamsStack这个栈,就会先封装参数,再执行PreparableInterceptor,最后执行ModelDrivenInterceptor
这样的话就会先将封装参数,然后执行你的逻辑,最后getModel方法才会返回你指定的对象了。
ModelDriver中有个方法是在执行完actionion之后,执行Result之前执行的,必须将属性refreshModelBeforeResult置为true,这样也可以更新model
public class ModelDrivenInterceptor extends AbstractInterceptor {
public void beforeResult(ActionInvocation invocation, String resultCode) {
ValueStack stack = invocation.getStack();
CompoundRoot root = stack.getRoot();
boolean needsRefresh = true;
Object newModel = action.getModel(); // 获得新赋值的model
// Check to see if the new model instance is already on the stack
for (Object item : root) {
if (item.equals(newModel)) { // 判断值栈中的model和新获得的model是不是同一个对象,是的话不更新值栈model,不是则移除model加入新的
needsRefresh = false; // 相同
}
}
// Add the new model on the stack
if (needsRefresh) { // 移除旧的,放入新的
// Clear off the old model instance
if (originalModel != null) {
root.remove(originalModel);
}
if (newModel != null) {
stack.push(newModel);
}
}
}