作者:江南白衣

   本文來(lái)自SpringSide WIki,請(qǐng)留意Wiki上的最新版本。

   Struts 1.2 其實(shí)已經(jīng)大不同,只要大家有簡(jiǎn)約的態(tài)度,即使我們?nèi)粘5腟truts,同樣可以寫(xiě)得非常精簡(jiǎn),不一定要如傳統(tǒng)觀念認(rèn)為的那么繁重,從而節(jié)省每天編碼的時(shí)間。

    Struts與Spring結(jié)合的基本知識(shí)請(qǐng)閱讀Struts使用要點(diǎn)。

1.DispatchAction

     以一個(gè)Controller響應(yīng)一組動(dòng)作絕對(duì)是Controller界的真理,Struts的DispatchAction同樣可以做到這點(diǎn)。

<action path="/admin/user" name="userForm" scope="request" parameter="method" validate="false">
    
<forward name="list" path="/admin/userList.jsp"/>
</action>

    其中parameter="method" 設(shè)置了用來(lái)指定響應(yīng)方法名的url參數(shù)名為method,即/admin/user.do?method=list 將調(diào)用UserAction的public ActionForward list(....) 函數(shù)。   

    public ActionForward unspecified(....) 函數(shù)可以指定不帶method方法時(shí)的默認(rèn)方法。

2. struts-config.xml使用通配符

     對(duì)一些CRUD的Action,可以使用通配符,如果這批action里某個(gè)action某個(gè)方法還存在特殊路徑,可以在代碼里直接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里詳細(xì)定義formBean的每個(gè)屬性。

    第一種是appfuse里使用的,定義DynaValidatorForm里,內(nèi)嵌一個(gè)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");
//設(shè)置form
userForm.set("user",user);

    第二種是用BeanValidatorForm,直接把Pojo作FormBean,無(wú)需繼承于FormBean接口。

 <form-bean name="userForm" type="org.springside.helloworld.domain.User"/>

//取得form Bean
ValidatorForm userForm = (BeanValidatorForm) form;User user = (User) userForm.getInstance();
//設(shè)置form
BeanUtils.copyProperties(userForm, user);
    第3種是用LazyValidatorForm ,特別適合于FormBean中并不包含POJO商業(yè)對(duì)象所有屬性的情況,因?yàn)橥ǔm?xiàng)目里都屬于這種情況,所以springside默認(rèn)使用lazyValidatorForm.

    比如User對(duì)象 有 id,name,status三個(gè)屬性,而form表單中只有id和name兩個(gè)input框,如果使用方法1,2,直接把user 作為 form bean,  user對(duì)象的status因?yàn)闆](méi)設(shè)值,將為null,  copy 到作為商業(yè)對(duì)象的user時(shí),就會(huì)以null覆蓋原值。而lazyBean就沒(méi)有這個(gè)問(wèn)題,如果form中沒(méi)有status屬性,它不會(huì)將它c(diǎn)opy給商業(yè)對(duì)象。

    另外,apache commons-beantuils 1.7.0的lazybean仍有小bug,需要使用commons-1.7.1 snapshot版,而且它直接提供下載的snapshot版缺少了幾個(gè)class,應(yīng)使用springside提供的版本。

<form-bean name="bookForm" type="org.apache.struts.validator.LazyValidatorForm"/>
 
BeanUtils.copyProperties(user, form);
     
 注意User對(duì)象被自動(dòng)綁定,默認(rèn)Integer id 在空值時(shí)會(huì)被賦值為0,需要增加converter,讓其默認(rèn)為null,雖然也可以在web.xml里進(jìn)行相關(guān)配置,但還是在基類里配置了比較安全。
static {
ConvertUtils.register(
new IntegerConverter(null), Integer.class);
}

  4. 一些不必受困于Struts機(jī)制的簡(jiǎn)化寫(xiě)法

    一些簡(jiǎn)便直接的方法,大家可不必太受困于Struts的機(jī)制:

  4.1 不在struts-config.xml配置jsp路徑,直接在代碼里跳轉(zhuǎn)

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, 設(shè)<jodd:form bean="bookForm">

4.4 不用i18N地使用Message與Error

   Struts的ActionMessages很常用,但只接收i18N的key作為輸入?yún)?shù),老定義i18n很麻煩,偏方之一就是設(shè)一個(gè)message= {0},然后直接new ActionMessage("message", message);

5. 終極化簡(jiǎn)--StrutsEntityAction

 SpringSide封裝的EnttiyCRUDAction,,每個(gè)包含了CRUD操作的Action僅需如下代碼,詳細(xì)請(qǐng)閱讀SpringSide的Struts封裝

public class UserAction extends StrutsEntityAction<User,UserManager> {
     
private UserManager userManager;
     
public void setUserManager(UserManager userManager) {
           
this.userManager = userManager;
     }
   }