|
Struts要與Spring結合使用,主要的方法就是讓Struts知道Spring的存在,以讓Spring與其管理相關的組件,避免在程式中直接撰寫相關組件的依賴關係建立。 首先要在Struts的struts-config.xml中使用<plug-in>標籤註冊org.springframework.web.struts.ContextLoaderPlugIn: ...
<plug-in className="org.springframework.web. → struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="/WEB-INF/beans-config.xml, /WEB-INF/..."/> </plug-in> ... 有幾個方法可以讓您取得Spring所管理的Bean,方法之一是Struts的Action改繼承 org.springframework.web.struts.ActionSupport,這個類別是Struts的Action抽象類別的實作,您 可以使用它的getWebApplicationContext()來取得ApplicationContext的實例,然後進一步取得Spring容器 所管理的Bean實例,例如: ...
public class SomeAction extends ActionSupport { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws Exception { ApplicationContext context = getWebApplicationContext(); SomeBean bean = (SomeBean) context.getBean("some"); ... return mapping.findForward("view"); } } ... 這種方式符合Struts的使用習慣,透過繼承來實作Action,並可得到Spring管理組件間關係的好處,但壞處就是Spring與Struts的API耦合在一起,而且在Action中包括了取得相依物件的邏輯,這並沒有善用Spring管理依賴注入的好處。 另一個方式是讓Struts的Action直接繼承它自己的抽象Action類,但讓Spring來管理Struts的Action物件,讓Action 物件也成為Spring容器管理下的一個Bean,這麼一來就可以直接使用依賴注入的方式注入相依物件,例如可以重新修改一下第一個 Struts 程式 中的HelloAction類別:
package onlyfun.caterpillar; 其中UserChecker類別的定義如下所示:
package onlyfun.caterpillar; UserChecker模擬商務層的一個檢查權限的物件,您要在Struts的Action中使用到UserChecker的實例,這可以交由 Spring來為您作依賴注入,您可以將HelloAction與UserChecker的實例都交給Spring容器來管理,例如在Bean定義檔中這 麼定義:
<?xml version="1.0" encoding="UTF-8"?> Action的實例現在已納入Spring的管理,那麼Struts在請求轉發時,要有一個中間代理機制,當請求要轉發至指定的Action之前,先轉發 至代理物件,由代理物件通知Spring以取得Spring所管理的Action實例來處理請求,並將處理結果返回給代理物件,再由代理物件返回給 Struts,這可以在struts-config.xml中使用 org.springframework.web.struts.DelegatingActionProxy的實例來作代理,例如:
<?xml version="1.0" encoding="UTF-8" ?> 在定義檔中注意使用了<plug-in>標籤加入ContextLoaderPlugIn,並指定了Spring的Bean定義檔之位置與名稱。 注意beans-config.xml中HelloAction的"name"屬性設定為"/hello",則<action>中的 "path"屬性也必須設定為"/hello",DelegatingActionProxy是藉著這個來找到Action實例並進行請求處理的,這個方 法的缺點就是要花功夫在兩個定義檔的名稱比對上,並不是那麼的方便。 您可以使用Spring的org.springframework.web.struts.DelegatingRequestProcessor來取代Struts自己的RequestProcessor,在struts-config.xml中定義: ...
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="/WEB-INF/beans-config.xml"/> </plug-in> <controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/> ... 這一次,可以直接將Struts的Action類別名稱寫在struts-config.xml,看來會比較直覺,例如: ...
<action path="/hello" type="onlyfun.caterpillar.HelloAction"/> ... 事實上並不會使用到"type"屬性的設定,撰寫出來只是為了看來比較清楚Action使用了哪一個類別,簡潔的寫法只要這樣就可以了: ...
<action path="/someAction"/> ... 同樣的,當請求轉發時,會由代理物件將請求轉發至Bean定義檔中具有相同名稱(/hello)的Action實例來處理。 |