細談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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章