细谈Struts2框架(三)Struts2框架之ModelDriven

所谓ModelDriven,意思是直接把实体类当成页面数据的收集对象,例如DepartmentAction。

假如要写一个Action,我们可以有三种方式:
    1. 直接在Action中定义所有需要的属性,然后再JSP页面中直接用属性名称来提交数据。
    坏处: 如果实体类的属性多,Action中也要定义相同的属性。
    2. 直接在Action中定义Department对象,并添加Get和Set方法,然后再Jsp页面中通过对象.属性的方式来给对象赋值。
    坏处: Jsp页面上表单域中的命名太长,代码不 简洁
    3. 利用ModelDriven机制,让DepartmentAction实现一个ModelDriven接口,同时实现接口中的方法,getModel()。这种方式相对于来说是比较好的,Action和JSP写起来都非常简单。 下面主要介绍 ModelDriven的机制原理:

【Struts2中ModelDriven使用】

Struts2中获取表单数据有两种方式:Field-Driven(属性驱动)Action和Model-Driven(模型驱动)。属性驱动使用Action的属性元素封装请求参数,而模型驱动是使用javaBean来封装来回请求参数。

我们可以根据Action属性的不同将它分为两类:Field-Driven(属性驱动)Action和Model-Driven(模型驱动)Action。
    1. Field-Driven(属性驱动)Action,Action拥有自己的属性,表单字段直接和Action的属性对应。
    2. 实现ModelDriven接口可以在action中直接获得例如User对象,它会将Object getModel()取得的User放到ValueStack中。 可以理解为将这个User对象的属性追加到了Action中。

使用ModelDriven接口需要实现一个方法getModel():


public class BaseAction<T> extends ActionSupport implements ModelDriven<T>{
	private Class classt; 
	private T t; 
	
	public BaseAction(){
		try {
			ParameterizedType type = (ParameterizedType) this.getClass()
					.getGenericSuperclass();
			this.classt = (Class) type.getActualTypeArguments()[0];
			this.t = (T) this.classt.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static final String LISTACTION="listaction"; 
	public static final String ADDUI="addUI"; 
	public static final String UPDATEUI="updateUI"; 
	public static final String ACTION2ACTION="action2action";
	
	@Override
	public T getModel() {
		return this.t;
	}

}

该方法返回一个用于接收用于输入数据的模型。在页面中,这个模型的对象中的属性可以直接通过属性名来访问,而不需要使用对象.属性来访问。在action中也不需要添加对象的getset方法,但是必须要在Action中进行new操作,ModelDriven使用泛型。 

【Struts2中模型驱动原理】
ModelDriven的实现主要是通过ModelDrivenInterceptor拦截器,该拦截器主要做的事就是调用Acton的getModel()方法,然后把返回的model压入值栈。所以我们在jsp页面中,直接通过对象的属性名就能直接赋值给对象。说明了,此时对象正是ValueStace中的一个root对象。

下面是ModelDrivenInterceptor的代码:

public class ModelDrivenInterceptor extends AbstractInterceptor {
 
    protected boolean refreshModelBeforeResult = false;
 
    public void setRefreshModelBeforeResult(boolean val) {
        this.refreshModelBeforeResult = val;
    }
 
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();
 
        if (action instanceof ModelDriven) {
            ModelDriven modelDriven = (ModelDriven) action;
            ValueStack stack = invocation.getStack();
            Object model = modelDriven.getModel();
            if (model !=  null) {
                stack.push(model);
            }
            if (refreshModelBeforeResult) {
                invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
            }
        }
        return invocation.invoke();
    }

ModelDrivenIntercptor中,即可以看到model对象被压入ValueStack中!



发布了181 篇原创文章 · 获赞 405 · 访问量 34万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章