習慣了Struts1中的單獨用ActionForm來封裝請求參數,一時間還不太習慣Struts2在Action中對請求參數進行封裝的模式,不過沒關係,在Struts2同樣可以使用VO來封裝對象的。
10.屬性驅動和模型驅動
模型驅動的意思是使用單獨的JavaBean來封裝請求參數,使之貫穿於整個MVC流程;而與之對應的屬性驅動則是使用屬性作爲貫穿MVC流程的信息攜帶者。進一步說來,模型驅動使用VO來封裝請求參數和處理結果,屬性驅動使用Action實例來封裝請求參數和處理結果。
說到這裏,是不是覺得與Struts1的ActionForm比較類似了,的確如此,但所不同的是ActionForm需要繼承基類,而此處的Model僅僅是一個POJO,除此之外,ActionForm要想與Action關聯起來必須在struts-config.xml文件中進行配置,而在Struts2中不需要這樣的操作,只是使用模型驅動的Action必須要實現ModelDriven接口,同時提供Object getModel()方法用於關聯Action和Model。
那麼Struts2又是如何將請求參數封裝到model中的呢?這個問題可以在struts-default.xml文件中得到解答,在struts-default.xml中有如下配置:
<interceptors>
……
<!--定義屬性驅動的攔截器-->
<interceptor name=”params”
class=”com.opensymphony.xwork2.interceptor.ParametersInterceptor” />
<!--定義模型驅動的攔截器-->
<interceptor name=”model-driven”
class=”com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor” />
……
<!--定義模型驅動的攔截器棧-->
<interceptor-stack name=”modelDrivenStack”>
<interceptor-ref name=”model-driven”/>
<interceptor-ref name=”basicStack”/>
</interceptor-stack>
……
<interceptor-stack name=”defaultStack”>
<interceptor-ref name=”model-driven”/>
<interceptor-ref name=”params”/>
</interceptor-stack>
</interceptors>
<!--定義Struts2默認的攔截器棧-->
<default-interceptor-ref name=”defaultStack” />
其中params攔截器負責提取請求的參數,如果是使用的屬性驅動模式,它還負責將請求參數傳給Action實例的屬性;而model-driven攔截器則負責把請求參數傳給模型的屬性。
下面給出一個使用模型驅動的示例程序:
VO對象User:
public class User{
private String name;
private String password;
public void setName(String name){
this.name = name;
}
public void setPassword(String password){
this.password = password;
}
public String getName(){
return name;
}
public String getPassword(){
return password;
}
}
Action:
public class LoginAction implements Action, ModelDriven<User>{
private User model = new User();
public User getModel(){
return model;
}
public String execute() throws Exception{
……
return SUCCESS;
}
}
採用模型驅動模式後,所有的處理結果都封裝在Model中,如果想要在JSP頁面上輸出屬性結果,可以使用<s:property value=”model.name”/>,當然,由於Struts2比較智能,當寫成<s:property value=”name”/>這樣時,也能正確輸出結果。