Web程式從Struts向Stripes架構的移植

來源:互聯網
上載者:User
web|程式

  摘要 把你的現有Struts應用程式移植到Stripes架構能夠簡化Web開發,並且這一移植過程要比你想象的更為容易。

  一、 引言

  把一個現有Java Web應用程式移植到一種新架構可能不是大多數開發人員最感興趣的問題。除了要花費時間學習一種新的Web架構外,例如標籤、國際化系統和校正等繁重的轉化過程可能會迫使每一位程式員考慮再三。我最近就面臨這樣的一個挑戰-從Struts進行移植。

  在決定移植一個應用程式前,應該首先問一下"為何不使用現在的架構?"在我看來,Struts是一種穩定的具有良好文檔的架構,並且有一大批開發人員社區成員,但是其配置很麻煩,而且其表單、行為、應用程式流程和校正的分離有時會帶來很多麻煩。這種情形在我的Struts應用程式不斷變大時越發糟糕。最後,純粹從一種維護的角度,我決定把它移植到一種新的架構。

  開始,我認為沒有一種架構(Java ServerFaces,Tapestry,WebWorks,Spring MVC)值得從Struts遷移向其遷移。例如JSF這樣的架構看上去極不友好。其它的,例如Tapestry和WebWorks,涉及到整頁整頁的看上去令人麻煩的國際化系統。而從配置角度來看,Spring MVC看上去並不比Struts好多少。我選擇的架構應該僅需適當的學習時間,還要與移植效益相稱;而且,它還一定要使我編碼、排錯與維護更為容易。

  二、 發現Stripes架構

  後來,我偶然發現了Stripes架構。就象Java社區中的許多發燒友一樣,我一直追隨著Ruby on Rails(RoR)現象。依我看來,Stripes是最接近於RoR哲學的Java MVC架構-簡單,漂亮,並且要求最小的配置。除了它的簡潔外,象我這樣一位Struts程式員,Stripes非常適合我的口味。應用程式流程和許多命名慣例都與之十分相似。Stripes中的ActionBeans就象Strut的Actions,而ForwardResolutions極象ActionForwards。因此,使用這一架構,我不必拋棄我所有以前的Struts知識。

  另外吸引我的是Stripes文檔。象架構本身一樣,文檔也是乾淨、清潔而簡練。其標籤庫文檔和API都具有良好的歸檔,而且該架構的每一種特徵幾乎都有相應的樣本源碼。這些優秀的文檔再加上我的現有Struts知識使我堅信,我可以快速地掌握這種Stripes架構。

  值得注意的是,Stripes還包括另外一些使其成為一種良好的AJAX平台的特徵,例如它提供了一種流式方案,該方案允許對AJAX實現進行改進的錯誤處理。然而,對於我來說,最終的決定因素還是我能夠清楚地看到它會使我的生活更容易些。我估計,在我的應用程式的行為/配置/校正部分,我只需使用約一半的代碼就夠了。更少的代碼意味著了更少的錯誤、更快的開發時間和更容易的錯誤修正。

  三、 移植過程

  我從視圖層開始移植,然後再向行為層移植。事實上,我也沒有很明確的邏輯思路;只是必須從某處開始,而視圖部分看起來更適合於作為一個起始點。

  (一) JavaServer Pages

  就象Struts一樣,Stripes使用JSP來實現其視圖層。我吃驚地發現,Stripes標籤庫非常類似於Struts的HTML taglib。事實上,我能夠使用這種統一替換方式來升級我的許多標籤。

  Stripes依賴於JSTL實現JSP視圖中的邏輯。我在我的應用程式中混合使用了Struts邏輯標籤和JSTL。通過把我的所有邏輯標籤移植到JSTL,我能夠利用JSTL的優越的if/else和case語句的能力處理,它們可能是很原始的或者根本不存在於Struts邏輯taglib中。

  (二) 國際化

  接下來,我要移植我的Struts的訊息資源。在配置端,所有要求的操作就是重新命名我的Struts訊息資源檔。在我的JSP中,我能夠使用統一替換方式把我的所有Struts message標籤(例如,<bean:message key="buttons.save"/>)替換為JSTL格式標籤(例如,<fmt:message key="buttons.save"/>)。這種JSTL格式標籤還支援可用於Struts中的訊息資源綁定。

  (三) 表單

  我的移植的最有意義的部分是去掉了我的Struts Action表單,這是在Action類中進行的,要求大量的XML標記和冗長的轉換,如下例所示:

<form-bean name="employeeUpdateForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="employeeid" type="java.lang.Long" />
<form-property name="firstname" type="java.lang.String" />
<form-property name="lastname" type="java.lang.String" />
<form-property name="phone" type="java.lang.String" />
<form-property name="email" type="java.lang.String" />
<form-property name="phone" type="java.lang.String" />
<form-property name="socialsecurity" type="java.lang.String" />
<form-property name="birthdate" type="java.lang.String" />
<form-property name="salary " type="java.lang.String" />
</form-bean>
public ActionForward executeAction(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {

Employee employee=new Employee();
DynaValidatorForm eaf = (DynaValidatorForm) form;
employee.setFirstname(eaf.getString("firstname"));
employee.setLastname(eaf.getString("lastname"));
employee.setPhone (eaf.getString("phone"));
employee.setEmail (eaf.getString("email"));
employee.setEmployeeid ((Integer)eaf.get("employeeid"));
employee.setSocialsecurity(Long.parseLong(eaf.getString("socialsecurity")));
employee.setBirthdate(MyUtils.convertStringToDate(eaf.getString("birthdate")));
employee.setSalary(MyUtils.convertStringToBigDecimal(eaf.getString("salary")));
EmployeeDAOService.updateEmployee(employee);
return new ActionForward(mapping.getForward());
}
  另一方面,Stripes表單處理允許你把你的域對象用作一個表單使用:

public class UpdateEmployeeActionBean implements ActionBean {
private ActionBeanContext context;
private Employee employee;
public ActionBeanContext getContext() {
return context;
}
public void setContext(ActionBeanContext context) {
this.context = context;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Employee getEmployee() {
return this.employee;
}
@DefaultHandler
public Resolution update() {
EmployeeDAOService.updateEmployee(employee);
return new ForwardResolution("/employees/updateEmployee.jsp");
}
}
  在大多數情況中,我能夠嵌入我的域對象的一個副本作為我的Stripes ActionBean類的一個屬性並且僅包括涉及把該對象移入/移出我的持久層的代碼部分。我把所有表單處理都交給了Struts Action來實現,包括初始化配置、把表單強制轉換成適當的類以及從域對象中來迴轉換資料(約30%的代碼是在大多數Action類中實現的)。在Stripes中並不需要這樣。

  簡言之,把域對象作為你的ActionBean類的一個屬性嵌入,為該類提供了getter和setter方法。總之,所有有趣的地方(包括列表)都在HTML視圖的表單中體現出來。

  所有我對錶單的操作也都可以通過查詢串參數方式來實現。我僅把這些參數作為我的ActionBean的一個屬性,而如果它們是請求的一部分的話,可以把它們自動地複製到相應的域中。

  (四) 校正

  與表單或標籤移植相比,把Struts校正移植到Stripes要求更多的工作。在我的應用程式中,我必須在Stripes ActionBean類內部使用Java 5.0註解重寫在validation.xml檔案中的校正配置。Stripes還為你提供一種良好的基於類型的校正。當使用者輸入錯誤值時,不需要使用者進行任何配置,Stripes就可以把HTML表單返回給他們(例如,在一個數字或日期域中的字元)。表單能夠被自動返回並帶有一條向方便使用顯示的訊息,最後出錯域被高亮顯示。

  (五) 應用程式流程程

  轉換我的Struts應用程式的控制流程可能是唯一遠離Struts思維的一個地方。在Struts中,控制流程(URL請求綁定、行為和結果檢視)都以XML標記形式產生並且被集中放到struts-config.xml檔案中。在行為層外進行產生使Struts綁定更為靈活。它們沒有被寫入程式碼到行為層中,而單個行為可以容易地與不同的輸入URL和轉寄進行耦合。這種方式的不好的地方在於,Struts配置量可能會急劇增加而成為麻煩。控制流程與行為層的分離還會使在整個請求周期中的調試相當困難。

  為此,Stripes共提供了三種不同方式以便把請求映射到行為層:

  1. 使用註解把一個ActionBean顯式綁定到一個URL;

  2. 允許Stripes在啟動期間基於ActionBean類路徑和應用程式URL之間的相似性猜測它的ActionBean的綁定;

  3. 類路徑通過使用Stripes useBean標籤,把一個JSP綁定到任何ActionBean,或調用應用程式中一個Java類的任何方法。

  儘管與Struts配置相比,前兩種方法似乎有點"寫入程式碼"特徵,但是useBean標籤提供了大量的靈活性。藉助於該標籤,JSP可以存取多個ActionBean或類以得到其所需要的內容。

  四、 結論

  當選擇一個新架構時,遷移的容易性(既包括學習新架構方面,也包括移植你的現有代碼方面)是要考慮的要素之一,但是不應該過多地強調。是的,你可能已經在學習一種現有架構上做出很大的投資並且在你的下一個MVC平台上保留這些投資的一部分更好一些。而且,如果你能夠在幾周而不是在幾個月內移植完你的應用程式則最好不過。但是不管問題是多麼容易或是多麼愉快,你還是要首先應該決定是否目標能夠滿足你的真正要求。對於我來說,能夠把幾乎一半的代碼放到我的行為層中而把表單、配置和校正放到一起是我最關心的問題。Stripe文檔的品質及其它問題則為次要。

相關文章

Cloud Intelligence Leading the Digital Future

Alibaba Cloud ACtivate Online Conference, Nov. 20th & 21st, 2019 (UTC+08)

Register Now >

11.11 Big Sale for Cloud

Get Unbeatable Offers with up to 90% Off,Oct.24-Nov.13 (UTC+8)

Get It Now >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。