Struts 1.2 其實已經大不同,只要大家有簡約的態度,即使我們日常的Struts,同樣可以寫得非常精簡,不一定要如傳統觀念認為的那么繁重,從而節省每天編碼的時間。
Struts與Spring結合的基本知識請閱讀Struts使用要點。
1.DispatchAction
以一個Controller響應一組動作絕對是Controller界的真理,Struts的DispatchAction同樣可以做到這點。
<action path="/admin/user" name="userForm" scope="request" parameter="method" validate="false">
<forward name="list" path="/admin/userList.jsp"/>
</action>
其中parameter="method" 設置了用來指定響應方法名的url參數名為method,即/admin/user.do?method=list 將調用UserAction的public ActionForward list(....) 函數。
public ActionForward unspecified(....) 函數可以指定不帶method方法時的默認方法。
2. struts-config.xml使用通配符
對一些CRUD的Action,可以使用通配符,如果這批action里某個action某個方法還存在特殊路徑,可以在代碼里直接new ActionForward("/foo.jsp");
<action path="/admin/*" name="{1}Form" parameter="method" scope="request" validate="false">
<forward name="list" path="/WEB-INF/pages/admin/{1}List.jsp"/>
<forward name="edit" path="/WEB-INF/pages/admin/{1}Form.jsp"/>
<forward name="success" path="/admin/{1}.do?method=list" redirect="true"/>
</action>
3.No FormBean
Struts 1.2.7 之后一共有三種方法,不需要定義FormBean Java類也不需要在struts-config.xml里詳細定義formBean的每個屬性。
第一種是appfuse里使用的,定義DynaValidatorForm里,內嵌一個pojo屬性.
<form-bean name="userForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="user" type="org.appfuse.model.User"/>
</form-bean>
//取得form DynaActionForm userForm = (DynaActionForm) form;
User user = (User) userForm.get("user");
//設置form
userForm.set("user",user);
第二種是用BeanValidatorForm,直接把Pojo作FormBean,無需繼承于FormBean接口。
<form-bean name="userForm" type="org.springside.helloworld.domain.User"/>
//取得form Bean
ValidatorForm userForm = (BeanValidatorForm) form;User user = (User) userForm.getInstance();
//設置form
BeanUtils.copyProperties(userForm, user);
第3種是用LazyValidatorForm ,特別適合于FormBean中并不包含POJO商業對象所有屬性的情況,因為通常項目里都屬于這種情況,所以springside默認使用lazyValidatorForm.
比如User對象 有 id,name,status三個屬性,而form表單中只有id和name兩個input框,如果使用方法1,2,直接把user 作為 form bean, user對象的status因為沒設值,將為null, copy 到作為商業對象的user時,就會以null覆蓋原值。而lazyBean就沒有這個問題,如果form中沒有status屬性,它不會將它copy給商業對象。
另外,apache commons-beantuils 1.7.0的lazybean仍有小bug,需要使用commons-1.7.1 snapshot版,而且它直接提供下載的snapshot版缺少了幾個class,應使用springside提供的版本。
<form-bean name="bookForm" type="org.apache.struts.validator.LazyValidatorForm"/>
BeanUtils.copyProperties(user, form);
注意User對象被自動綁定,默認Integer id 在空值時會被賦值為0,需要增加converter,讓其默認為null,雖然也可以在web.xml里進行相關配置,但還是在基類里配置了比較安全。
static {
ConvertUtils.register(new IntegerConverter(null), Integer.class);
}
4. 一些不必受困于Struts機制的簡化寫法
一些簡便直接的方法,大家可不必太受困于Struts的機制:
4.1 不在struts-config.xml配置jsp路徑,直接在代碼里跳轉
return new ActionForward("/foo/bar.jsp");
or
return new ActionForward("/foo/bar.jsp",true);
4.2 不走jsp,直接輸出字符串
ActionForward execute(....){
try {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(text);
} catch (IOException e) {
log.error(e);
}
return null;
}
4.3. 不依賴Struts Taglib,EL直接輸出FormBean 屬性
普通FormBean:${bookForm.image}
LazyValidatorForm:${bookForm.map.image}
其中bookForm 是formBean名。另一種輸出屬性的方式是使用jodd-form, 設<jodd:form bean="bookForm">
4.4 不用i18N地使用Message與Error
Struts的ActionMessages很常用,但只接收i18N的key作為輸入參數,老定義i18n很麻煩,偏方之一就是設一個message= {0},然后直接new ActionMessage("message", message);
5. 終極化簡--StrutsEntityAction
SpringSide封裝的EnttiyCRUDAction,,每個包含了CRUD操作的Action僅需如下代碼,詳細請閱讀SpringSide的Struts封裝
public class UserAction extends StrutsEntityAction<User,UserManager> {
private UserManager userManager;
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
}