讓struts1來模擬struts2

2021-08-24 18:27:56 字數 3830 閱讀 1054

公司裡的專案用的框架是常見的ssh,只是使用的是struts1和spring1,都略顯得有點老舊了。之前看了陣struts2,感覺比struts1先進了很多,但是我想公司是不可能隨便公升級框架的,正好這兩天閒著沒什麼事做,琢磨著該做些什麼了。於是我就想讓struts1模擬一些struts2的特性。

struts2取消了actionform,並且使action成為了多例項的模式,這樣在action裡就可以使用成員變數了,而在使用了param***後,表單中的值還會自動填充action的成員變數。

今天的目標就是讓struts1也來實現這個特性。

首先我們要使struts1的action成為多例項模式--這樣我們才能在action中使用成員變數,只要讓action由spring來管理就行了。這個很簡單,具體做法略。

接著我們要實現表單的值自動填充action的成員變數。在做這個之前我有兩重想法:

一種是使用類繼承的方式,通過編寫乙個抽象的action父類,在這個父類的execute方法裡,在呼叫正式的業務處理**之前,把表單中傳來的值賦給各個action子類的成員變數,然後在乙個抽象的方法doexecute中執行具體的業務處理,而這個doexecute就由每個子類去實現。

我們先不管具體的賦值操作時如何實現的,這種想法比較簡單,實現起來也很容易。但是我們都知道struts2裡的核心是***,在處理這個問題的時候實際上也是使用了param***,這種做法說不上什麼不好,只是既然我們想模擬它,那就模擬的更像一點吧。於是又有了第二種做法。

第二種就是通過使用spring aop來實現,很明顯這個賦值操作應該在action的execute方法執行前進行,我們這裡就使用spring裡的前置通知(也有叫前置增強的)來模擬struts2的param***了。

public class paramadvice implements methodbeforeadvice

//取出request

for(object arg : args)

}//為成員變數賦值

if(action != null && request != null)}}

接著我們就要為每個action來配置這個前置通知了,這裡我們使用自動建立**的方式來配置。

之後,所有的action的成員變數在呼叫execute方法之前就會被表單裡的值所填充。

這裡使用defaultadvisorautoproxycreator為所有的action bean來建立**,其實我原先是想用beannameautoproxycreator來為指定的action bean來建立**的,但是不知道為什麼如果我把action bean配置成singleton="false",那麼就無法被**,而我有試過對於一般singleton="false"的bean,**是會配置上去的。這個問題誰知道的話,希望指導一下。

最後我們再研究下如何為action裡的成員變數賦值,如果成員變數都是簡單型別,那麼很簡單,但是若成員變數是複雜型別,比如有個自定義的user型別,user型別裡又有乙個自定義的address型別,而表單中提交的鍵值對是user.address.name=110,這樣我們就要遞迴的建立外層物件,為最內層變數賦值,最後把物件設定到action中去。這裡我們用反射來實現。

public class webparamutils catch (securityexception e1) catch (illegalargumentexception e1) catch (instantiationexception e1) catch (illegalacces***ception e1) catch (nosuchmethodexception e1) catch (invocationtargetexception e1) }}

}

public class reflectionutils catch (nosuchfieldexception e)

}return null;

}//呼叫物件的set方法

public static void invokesetmethod(object instance, field field, object fieldvalue)

throws securityexception, nosuchmethodexception,

illegalargumentexception, illegalacces***ception,

invocationtargetexception

//呼叫物件的get方法

public static object invokegetmethod(object instance, field field)

throws securityexception, nosuchmethodexception,

illegalargumentexception, illegalacces***ception,

invocationtargetexception

// 獲得指定變數的值

public static object getfieldvalue(object instance, string fieldname)

throws illegalargumentexception, illegalacces***ception

// 獲得指定變數的值

public static object getfieldvalue(object instance, field field)

throws illegalargumentexception, illegalacces***ception

//為物件設定屬性值

public static void setfieldforobject(object instance, string fieldname,

object fieldvalue) throws instantiationexception,

illegalacces***ception, securityexception,

illegalargumentexception, nosuchmethodexception,

invocationtargetexception

// 遞迴

setfieldforobject(entity, substring, fieldvalue);

// 把實體物件設定到父物件中

invokesetmethod(instance, field, entity);

}} else }}

}

再做乙個測試action

一切都配置好之後,可以再瀏覽器中輸入http://localhost:8080/case1/test.do?code=1&msg=2&user.id=3&user.name=4&user.address.id=5&user.address.addr=6,你就會在控制台上看到

在action呼叫execute方法前,為成員變數賦值

********************====

code=1

msg=2

user.id=3

user.name=4

user.address.id=5

user.address.addr=6

這樣我們就大功告成了,以上的兩種方案都有經過測試,雖然第二種做法比較新穎一點,但是我們知道spring aop使用了**,而且這裡還使用了cglib**,而cglib並不適於建立多例項模式bean的**(和jdk動態**相比),所以效能上估計會有點損失,顯然第一種方案會好點,其實具體的效能怎樣我也沒有測過,有誰感興趣的話可以去試試。

Struts 1的模擬實現

1 寫個抽象類 含有乙個抽象方法exeute,引數為httpservletrequest與httpservletresponse,返回乙個字 符串 返回的jsp頁面 2 隨便寫幾個action類,來繼承上面的抽象類實現抽象方法 3 寫個servlet 核心控制器actionservlet a 得到請...

struts1學習筆記1

1.struts是mvc模式的經典應用。它主要是提供乙個好的控制器和一套定製的標籤庫 優點 結構層次分明,高重用性。2.開發環境搭建 建立乙個struts1的工程,匯入struts1的jar包 在web inf目錄中新增乙個struts config.xml,配置web.xml檔案中新增處理stru...

struts1 上傳檔案

1.dto 類中寫好 private formfile formfiletaobao null 屬性。2.jsp 頁面中file對應的寫好屬性的名稱 如 選擇檔案 3.注意form中的屬性設定,例如 4.然後在寫action類 x xx x form 轉換dto類物件。formfile formfi...