試著把在Struts 1下所寫的權限程式碼移植到Struts 2,有看到Struts 2的有個建議作法與Struts 1是可以mapping的。就是Struts2的Action去implement兩個介面:
public class RoleAction extends BaseAction implements Preparable, ModelDriven<AaModel> {
private AaMgr aaMgr;
public void setAaMgr(AaMgr aaMgr) {
this.aaMgr = aaMgr;
this.logger.debug("(1)call setXX when this action initialize.");
}
private AaModel aaModel;
public void prepare() throws Exception {
if (this.aaModel == null) {
this.aaModel = new AaModel();
}
this.logger.debug("(2)Struts2 call prepare when post this action");
}
public AaModel getModel() {
this.logger.debug("(3)Struts2 call back getModel after prepared" );
return this.aaModel;
}
public String addRole() {
this.logger.debug("(4)Run action methods after get Model" );
// ...
return SUCCESS;
}
}
上面的片斷程式碼可以看出其執行順序,Spring的depency Injection在action被new起後只執行一次;之後每次request,依序是prepare、getModel以及action的method如execute等。這時model物件,其實就相當於Struts 1的ActionForm,在prepare事先new出或依post過來屬性當key找出model的instance,在對model的操作賦值後,便可以OGNL格式傳到前端。
假設AaModel裡有個rolename屬性,則可用<s:property value="rolename"/>顯示,若RoleAction本身也有rolename屬性,仍會以Model為主,除非是這麼指定<s:property value="[1].rolename"/>。在Struts2裡有個Value Stack設計,Stack是後進先出格式,是故若有相同屬性名,RoleAction先被new,其rolename就先被push,之後getModel,AaModel也有rolename,便壓在RoleAction的rolename之上,預設取出最上面的rolename(即[0].rolename)。
剩兩天了,醜媳婦總要見公婆了。